Java has discovered application components that could indicate a security concern

When starting a particular web based application Java popped up the following dialog:

Java has discovered application components that could indicate a security concern

The dialog asks us if we want to Block potentially unsafe components so to continue we should click no. However users tend to not really read such messages and click Yes which leads to this error:

Error connecting to Central Configuration

Java is not to blame here, it’s perfectly valid to popup this message since the vendor has signed a part of it’s code but failed to sign other parts (in which case not signing at all would have been a better choice, but at least the vendor is trying).

So how do we make this message go away?

Method 1: Java Control Panel
Open the Java Control Panel and go to the Advanced Tab. Expand the Security node and set the Mixed code option to Disable verification:

Advanced | Security | Mixed code | Disable verification

The disadvantage for this method is obviously that it’s a lot of work to set this manually for all users. So on to method 2…

Method 2: edit deployment.properties file
Java stores it’s configuration in the deployment.properties file which is usually located in %appdata%\sun\java\deployment:

edit deployment.properties file

Using a deployment tool (or even the login script) we can easily copy a modified deployment.properties file. The risk in this approach is that we overwrite the complete configuration.

A better approach is to just add the line we need with a script which could be as simple as this:

echo deployment.security.mixcode=DISABLE >>"%AppData%\Sun\Java\Deployment\deployment.propertes"

But if there already was a line for mixcode we will end up with two lines and which line will prefer?

In both approaches the file might actually be located in a different path for example in Windows 7 it’s in AppData\LocalLow…

Let’s see if method 3 will do a better job…

Method 3: change it programmatically

I figured that the best way to change Java configuration would be to use Java for it. I googled for a way to change the deployment.properties file programmatically but failed to find a good answer. I got a quick answer on stackoverflow though.

Java exploses a Config class that does what we need so using that I created a small tool to change the Mixed code setting.

When used without arguments (or /?) the possible commandline arguments and current setting are displayed:

image

Use the Disable argument (Java SetMixedCode Disable) to disable verification:

image

Note that you should not execute the tool with the .class extension (Java SetMixedCode.class) because it will throw an exception:

image

The tool can be download at the bottom of this page and includes source code.

If you are interested in the code, here it goes but please note that I didn’t write code in Java before so suggestion to improve are welcome!

import com.sun.deploy.config.Config;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.net.URL;

public class SetMixedCode {

    // taken from http://stackoverflow.com/questions/1010919/adding-files-to-java-classpath-at-runtime
    private static void addSoftwareLibrary(File file) throws Exception {
        Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
        method.setAccessible(true);
        method.invoke(ClassLoader.getSystemClassLoader(), new Object[]{file.toURI().toURL()});
    }

    // get Java Home Path
    private static String getJavaHome() {
        return System.getProperty("java.home");
    }

    // I am sure there is a smarter way to do this...
    private static String getJavaLib() {
        return getJavaHome() + File.separatorChar + "lib";
    }

    // load Class at runtime (so we don't need to add it to the ClassPath)
    private static void loadClass(String fileName) throws ClassNotFoundException {
        File file = new File((getJavaLib() + File.separatorChar + fileName));
        try {
            addSoftwareLibrary(file);
        } catch (Exception e) {
            throw new ClassNotFoundException(String.format("Failed to load %s\n%s",
                    file.getAbsolutePath(), e.getStackTrace()));
        }
    }

    public static void main(String[] args) {
        int MixedMode = 0;

        System.out.println("SetMixedMode (c) 2013 Remko Weijnen");
        System.out.println("Changes Java's Mixed code setting.\n");

        try {
           loadClass("deploy.jar");
        } catch (Exception e) {
            System.err.println(e.getStackTrace());
        }

        // Print config filename
        System.out.println(String.format("Config filename: %s", Config.getUserHome() +
                File.separatorChar + Config.getPropertiesFilename()));

        // Get current value
        System.out.println(String.format("Current Value: %s\n", Config.getProperty(Config.MIXCODE_MODE_KEY)));

        // Show commandline options if argument count is 0 or argument = /? or -h
        if (args.length == 0 || args[0].equalsIgnoreCase("/?") || args[0].equalsIgnoreCase("-h")) {
            System.out.println("Argument       Matching setting in Java Control Panel");
            System.out.println("-----------------------------------------------------------------");
            System.out.println("ENABLE         Enable - show warning if needed");
            System.out.println("HIDE_RUN       Enable - hide warning and run with protections");
            System.out.println("HIDE_CANCEL    Enable - hide warning and don't run untrusted code");
            System.out.println("DISABLE        Disable verification (not recommend)\n");
            System.exit(0);
        }

        // Parse Commandline argument
        if (args[0].equalsIgnoreCase("ENABLE")) {
            MixedMode = Config.MIXCODE_ENABLE;
        } else if (args[0].equalsIgnoreCase("HIDE_RUN")) {
            MixedMode = Config.MIXCODE_HIDE_RUN;
        } else if (args[0].equalsIgnoreCase("HIDE_CANCEL")) {
            MixedMode = Config.MIXCODE_HIDE_CANCEL;
        } else if (args[0].equalsIgnoreCase("DISABLE")) {
            MixedMode = Config.MIXCODE_DISABLE;
        } else {
            System.err.println(String.format("Argument %s was not recognized", args[0]));
            System.exit(1);
        }

        if (Config.getMixcodeValue() != MixedMode) {
            System.out.println(String.format("Setting Mixed Code to: %s", args[0].toUpperCase()));
            Config.setMixcodeValue(MixedMode);
            System.out.println("Commiting changes");
            Config.store();
        } else {
            System.out.println("no changes required.");
        }
    }
}

[wpfilebase tag="file" id=1 /]