2017-05-27 3 views
0

Wir aktualisieren vor kurzem Tomcat zu 8.5.6 von 8.0.32, und wir treffen eine AccessControlException, wenn versuchen, /opt/apache-tomcat-8.5.6_1/webapps/example/WEB-INF/classes/com/sun/xml/internal/ws/runtime/config/jaxb.properties laden, und ich debuggen den Quellcode zwischen Tomcat 8.5.6 und 8.0.32 , es ist anders in org.apache.catalina.loader.WebappClassLoaderBase.findResourcetomcat8.0 und tomcat8.5.6 WebappClassLoaderBase

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; 
} 

Wie Sie, tomcat8.0 Last Ressource von AccessController.doPrivileged sehen kann, aber in tomcat8.5.6 es die Ressource direkt geladen werden, denke ich, das ist, warum ich eine Ausnahme bekam

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) 

diese Datei von geladen wird 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)}); 
    } 

Hat jemand gleiches Problem begegnen? oder es gibt einige andere Probleme. Vielen Dank.

Antwort

1

Nach drei Tagen der Erforschung, jetzt verwende ich jaxws-rt statt Standardimplementierung in JDK und wie Sie aus dem Code in JDK lesen:

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()); 
} 

Wenn es JDK interne, wird die Instanz mit spezifischen erstellen Privileg und tomcat Ressource von doPrivileged in tomcat8.0 bekommen, aber es ist anders in tomcat8.5, so dass es die Ressource ohne Privileg nicht bekommen kann

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") 

So wechselte ich zu externen jaxws-rt, und es wird das schaffen Beispiel direkt. Ich füge einfach jaxws-rt zu pom hinzu.

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