tomcat8.0和tomcat8.5.6 WebappClassLoaderBase [英] tomcat8.0 and tomcat8.5.6 WebappClassLoaderBase

查看:789
本文介绍了tomcat8.0和tomcat8.5.6 WebappClassLoaderBase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近从8.0.32将tomcat更新到8.5.6,并且在尝试加载 / opt / apache-tomcat时遇到 AccessControlException -8.5.6_1 / webapps / example / WEB-INF / classes / com / sun / xml / internal / ws / runtime / config / jaxb.properties ,我在tomcat 8.5之间调试源代码。 6和8.0.32,它在 org.apache.catalina.loader.WebappClassLoaderBase.findResource

We update tomcat to 8.5.6 from 8.0.32 recently, and we meet a AccessControlException when try to load /opt/apache-tomcat-8.5.6_1/webapps/example/WEB-INF/classes/com/sun/xml/internal/ws/runtime/config/jaxb.properties, and I debug the source code between tomcat 8.5.6 and 8.0.32, it's different in org.apache.catalina.loader.WebappClassLoaderBase.findResource

Tomcat8.0

public URL findResource(final String name) {

    if (log.isDebugEnabled())
        log.debug("    findResource(" + name + ")");

    checkStateForResourceLoading(name);

    URL url = null;

    String path = nameToPath(name);

    ResourceEntry entry = resourceEntries.get(path);
    if (entry == null) {
        if (securityManager != null) {
            PrivilegedAction<ResourceEntry> dp =
                new PrivilegedFindResourceByName(name, path);
            entry = AccessController.doPrivileged(dp);
        } else {
            entry = findResourceInternal(name, path);
        }
    }
    if (entry != null) {
        url = entry.source;
        entry.webResource = null;
    }

    if ((url == null) && hasExternalRepositories) {
        url = super.findResource(name);
    }

    if (log.isDebugEnabled()) {
        if (url != null)
            log.debug("    --> Returning '" + url.toString() + "'");
        else
            log.debug("    --> Resource not found, returning null");
    }
    return url;
}

Tomcat8.5.6

public URL findResource(final String name) {

    if (log.isDebugEnabled())
        log.debug("    findResource(" + name + ")");

    checkStateForResourceLoading(name);

    URL url = null;

    String path = nameToPath(name);

    WebResource resource = resources.getClassLoaderResource(path);
    if (resource.exists()) {
        url = resource.getURL();
        trackLastModified(path, resource);
    }

    if ((url == null) && hasExternalRepositories) {
        url = super.findResource(name);
    }

    if (log.isDebugEnabled()) {
        if (url != null)
            log.debug("    --> Returning '" + url.toString() + "'");
        else
            log.debug("    --> Resource not found, returning null");
    }
    return url;
}

如你所见,tomcat8.0通过AccessController.doPrivileged加载资源,但是在tomcat8.5.6中,它直接加载资源,我认为这就是我得到异常的原因

As you can see, tomcat8.0 load resource by AccessController.doPrivileged, but in tomcat8.5.6, it load the resource directly, I think that's why I got a Exception

java.security.AccessControlException: access denied 
("java.io.FilePermission" 
"/opt/apache-tomcat-8.5.6_1/webapps/example/WEB-INF/classes/com/sun/xml/internal/ws/runtime/config/jaxb.properties" 
"read")

java.lang.IllegalStateException: MASM0003: Default [ jaxws-tubes-default.xml ] configuration file was not loaded
        at com.sun.xml.internal.ws.assembler.MetroConfigLoader.init(MetroConfigLoader.java:133)
        at com.sun.xml.internal.ws.assembler.MetroConfigLoader.<init>(MetroConfigLoader.java:104)

此文件由 MetroConfigLoader ,

private static JAXBContext createJAXBContext() throws Exception {
        return isJDKInternal()?(JAXBContext)AccessController.doPrivileged(new PrivilegedExceptionAction<JAXBContext>() {
            public JAXBContext run() throws Exception {
                return JAXBContext.newInstance(MetroConfig.class.getPackage().getName());
            }
        }, createSecurityContext()):JAXBContext.newInstance(MetroConfig.class.getPackage().getName());
    }

    private static AccessControlContext createSecurityContext() {
        PermissionCollection perms = new Permissions();
        perms.add(new RuntimePermission("accessClassInPackage.com.sun.xml.internal.ws.runtime.config"));
        perms.add(new ReflectPermission("suppressAccessChecks"));
        return new AccessControlContext(new ProtectionDomain[]{new ProtectionDomain((CodeSource)null, perms)});
    }

有没有人遇到同样的问题?或者还有其他一些问题。谢谢。

Does anyone meet same issue? or there is some other issues. thanks.

推荐答案

经过三天的研究,现在我用 jaxws-rt 而不是JDK中的默认实现,并且您可以从JDK中的代码中读取:

After three days researching, now I use jaxws-rt instead of default implementation in JDK, and as you can read from the code in JDK:

private static JAXBContext createJAXBContext() throws Exception {
        return isJDKInternal()?(JAXBContext)AccessController.doPrivileged(new PrivilegedExceptionAction<JAXBContext>() {
            public JAXBContext run() throws Exception {
                return JAXBContext.newInstance(MetroConfig.class.getPackage().getName());
            }
        }, createSecurityContext()):JAXBContext.newInstance(MetroConfig.class.getPackage().getName());
}

如果它是JDK内部的,它将创建具有特定权限的实例,并且tomcat通过tomcat8.0中的doPrivileged来获取资源,但是在tomcat8.5中它是不同的,所以它无法获得没有权限的资源

If it's JDK internal, it will create the instance with specific privilege, and tomcat get resource by doPrivileged in tomcat8.0, but it's different in tomcat8.5, So it can't get the resource without privilege

java.security.AccessControlException: access denied ("java.io.FilePermission" 
"/opt/apache-tomcat-8.5.6_1/webapps/example/WEB-INF/classes/com/sun/xml/internal/ws/runtime/config/jaxb.properties" 
"read")

所以我更改为外部 jaxws-rt ,它将直接创建实例。我只需将 jaxws-rt 添加到pom。

So I changed to external jaxws-rt, and it will create the instance directly. I just add jaxws-rt to pom.

 <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>2.2.10</version>
 </dependency>

这篇关于tomcat8.0和tomcat8.5.6 WebappClassLoaderBase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆