RobertG
RobertG

Reputation: 1696

Disable "internet access" for JVM?

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

Answers (3)

RobertG
RobertG

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:

  • Start the test case with JVM arguments -Djava.security.manager=default -Djava.security.policy=/java.policy
  • 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

Dolda2000
Dolda2000

Reputation: 25855

Admittedly, I haven't tested this, but I would think it should be possible to create java.net.SocketImplFactory which creates SocketImpls 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 SecurityExceptions rather than SocketExceptions or other IOExceptions, which may be important to test the error handling code correctly.

Upvotes: 0

Joop Eggen
Joop Eggen

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

Related Questions