Reputation: 1696
I'd like to know if there is a way to tell the JVM that it cannot connect to any web resource for a certain Java program, or to immediately fail when doing so, i.e. to do a software equivalent of turning off internet access with a hardware switch. This is to assist an automated test, disabling the system's firewall is no option for me.
Background: I'm currently working on a Java issue where XML identity transformation does not work with a DOCTYPE referenced in XML like this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px"
height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
<!-- content.... -->
</svg>
The standard behavior of DocumentBuilderFactory, TransformerFactory etc. is to access the web for the missing entities. While the fix suggested https://stackoverflow.com/a/9398602/1143126 (a NullEntityResolver) resolved most of my problems, I'd like to test this functionality for regression in an automated way in an "offline environment".
Upvotes: 15
Views: 6510
Reputation: 1696
The comment by Dunes helped a lot (issue How to disable all network connections in Java is related), I overlooked that other question.
Here is what I will use to prevent network connections:
As java.policy, I use the default file I found with my Java installation, and added the following lines s.t. stuff works with TestNG:
// // additional permissions for running TestNG // //
// TestNG reads a lot of properties...
permission java.util.PropertyPermission "*", "read";
// TestNG connects to a local port for debugging, and does some reflection magic
permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
// needs at least read access to (default) test suite folder location
permission java.io.FilePermission "C:/Users/<me>/AppData/Local/Temp/-", "read, write";
// if the test case (or, data provider) accesses any other files, add their location. or do it the lazy way:
permission java.io.FilePermission "C:/-", "read, write";
With that configuration, any access to an external source such as www.w3.org will result in an AccessControlException:
javax.xml.transform.TransformerException: java.security.AccessControlException: access denied (java.net.SocketPermission www.w3.org:80 connect,resolve)
Upvotes: 3
Reputation: 25855
Admittedly, I haven't tested this, but I would think it should be possible to create java.net.SocketImplFactory
which creates SocketImpl
s that raise appropriate exceptions when eg. connect
is called.
As others have pointed out, there is also the possibility to define a security manager. The main difference would be, I guess, what kind of exceptions would be thrown by that. I don't think there's any way to prevent such a solution from throwing SecurityException
s rather than SocketException
s or other IOException
s, which may be important to test the error handling code correctly.
Upvotes: 0
Reputation: 109547
You can use an XML catalog storing the external schemas (xsd+dtd) on your local disk. That speeds up normal processing too, and allows fast offline development.
It is a standard mechanism.
(Especially worthwile for XHTML as there is a large amount of HTML entities.)
Upvotes: 1