简体   繁体   中英

java jre 7u45 breaks classloader.getResources()?

I have code to iterate over the results of classLoader.getResources("META-INF/MANIFEST.MF") to return the list of jars on the class path. This worked fine from 1.6.0_18 all the way to 1.7.0_40. Now 1.7.0_45 breaks this by showing a security warning popup about mixed signed/unsigned code.

Small self contained testcase to demonstrate problem:

package testcase;
import java.io.*;
import java.net.*;
import java.util.Enumeration;
import java.util.logging.*;
public class TestCase {
    public static void main(String[] args) {
        getAllJarUrls();
    }

    public static void getAllJarUrls() {
        try {
            final Enumeration<URL> mfUrls = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
            while (mfUrls.hasMoreElements()) {
                URL jarUrl = mfUrls.nextElement();
                if (!jarUrl.getProtocol().equals("jar")) {
                    continue;
                }
                try {
                    System.out.println(jarUrl.toURI());
                } catch (URISyntaxException ex) {
                    Logger.getLogger("testcase").log(Level.SEVERE, null, ex);
                }
            }
        } catch (IOException e) {
            Logger.getLogger("testcase").log(Level.SEVERE, null, e);
        }
    }
}

Launch this with a jnlp (jar signed with a valid certificate) as:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://localhost/test" href="test.jnlp">
    <information>
        <title>test</title>
        <vendor>test</vendor>
      </information>
    <security><all-permissions/></security>
    <resources>
        <jar href="testcase.jar" main="true" download="eager"/>
    </resources>
    <application-desc main-class="testcase.TestCase"/>
</jnlp>

When run, have the console visible, and hit '5' for verbose output. then click 'block' on the security prompt to see the exception. Clicking allow will let the code run normally, but this is not an acceptable user experience . especially since our application has to be able to start without user input.

Output under 1.7.0_45 is as follows:

CacheEntry[http://localhost/test/testcase.jar]: updateAvailable=true,lastModified=Tue Oct 15 21:09:21 CDT 2013,length=6314
jar:file:/C:/jre32/1.7.0_45/lib/javaws.jar!/META-INF/MANIFEST.MF
jar:file:/C:/jre32/1.7.0_45/lib/deploy.jar!/META-INF/MANIFEST.MF
jar:file:/C:/jre32/1.7.0_45/lib/plugin.jar!/META-INF/MANIFEST.MF
jar:file:/C:/jre32/1.7.0_45/lib/deploy.jar!/META-INF/MANIFEST.MF
Trace level set to 5: all ... completed.Trace level set to 5: all ... completed.
security: resource name "META-INF/MANIFEST.MF" in http://localhost/test/testcase.jar : java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://localhost/test/testcase.jar

The testcase.jar is signed. It even has all the new manifest attributes included: Application-Name: testcase Permissions: all-permissions Codebase: *

A diff of the decompiled CPCallBackHandler from deploy.jar from 7u40 to 7u45 shows significant changes. It looks like the changes for LiveConnect have borked the existing functionality. And no, there's no LiveConnect involved here.

Has anyone else run into this? Suggestions for a workaround? File a bug?

(note: also posted on the OTN java forums, but I'm hoping for a faster answer here :).

Thanks, Chris

Add this to the manifest of the jar:

Trusted-Library: true

Documented here .

A warning though about the Trusted-Location - from the linked documentation -

The Trusted-Library attribute is used for applications and applets that are designed to allow untrusted components. No warning dialog is shown and an application or applet can load JAR files that contain untrusted classes or resources

So use this if you want to allow untrusted resources (is the way I read this).

The root of the problem is that the manifest iteration is including the unsigned resources associated with web-start itself (javaws.jar, deploy.jar).

I resolved my problem by using - JARDesc[] jars = JNLPClassLoader.getLaunchDesc().getResources().getEagerOrAllJarDescs(true);

We started experiencing a problem with classloader.getResourceAsStream() with 7u45. We had been getting by with signing the JARs but not embedding JNLP-INF/{APPLICATION.JNLP,APPLICATION_TEMPLATE.JNLP} (because we needed two unsigned application.jnlp variants, with different heap settings).

Anyway we fixed this problem by embedding JNLP-INF/APPLICATION_TEMPLATE.JNLP . Just posting in case anyone else has this particular problem.

We have this Problem with an application based on Netbeans RCP. Netbeans loads every Manifest-File to read its own entrys. That leads to a Security-Exception for every JAR included in the application. It seems to us that Java considers the Manifest-File itself to be an untrusted resource. Don't know if this is intended or bug.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM