Re: Jini client inside Tomcat - FilePermission required to unmarshall a service item
Peter Jones <[email protected]> Wed, 2 Jan 2008 14:39:50 -0500
| Newsgroups | gmane.comp.java.sun.jini |
|---|---|
| Message-ID | <20080102193950.GA14282@east> |
On Mon, Dec 31, 2007 at 07:39:24AM -0700, Michal Kleczek wrote:
[snip]
> But the service proxy cannot be unmarshalled by the Reggie proxy
> (service interface class cannot be found). After some investigation
> it appears that when PreferredClassLoader tries to load proxy
> interfaces and - since they are not preferred - delegates to it's
> parent loader (which is Tomcat's WebappClassLoader) some
> FilePermissions are checked (namely permissions to read from various
> directories containing web application classes eg.
> WEB-INF/classes). So if reggie proxy does not have appropriate
> permissions the check fails. Running with -Djava.security.debug I
> got the following stacktrace:
> access: access denied
> (java.io.FilePermission /home/mkleczek/apps/apache-tomcat-6.0.14/webapps/irepas/WEB-INF/classes/biz/xpro/meetings/IrepasMeetingsServi
> java.lang.Exception: Stack trace
> at java.lang.Thread.dumpStack(Thread.java:1206)
> at java.security.AccessControlContext.checkPermission(AccessControlContext.java:313)
> at java.security.AccessController.checkPermission(AccessController.java:546)
> at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
> at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
> at java.io.File.exists(File.java:731)
> at org.apache.naming.resources.FileDirContext.file(FileDirContext.java:822)
> at org.apache.naming.resources.FileDirContext.lookup(FileDirContext.java:205)
> at org.apache.naming.resources.ProxyDirContext.lookup(ProxyDirContext.java:294)
> at org.apache.catalina.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:1889)
> at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1757)
> at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872)
> at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
> at net.jini.loader.pref.PreferredClassLoader.loadClass(PreferredClassLoader.java:922)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
> at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
> at java.lang.Class.forName0(Native Method)
> at java.lang.Class.forName(Class.java:247)
> at net.jini.loader.pref.PreferredClassProvider.loadProxyInterfaces(PreferredClassProvider.java:1360)
> at net.jini.loader.pref.PreferredClassProvider.loadProxyClass(PreferredClassProvider.java:1241)
> at net.jini.loader.pref.PreferredClassProvider.loadProxyClass(PreferredClassProvider.java:1145)
> at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
> at net.jini.loader.ClassLoading.loadProxyClass(ClassLoading.java:240)
> at net.jini.io.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:373)
> at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1531)
> at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1493)
> at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
> at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
> at net.jini.io.MarshalledInstance.get(MarshalledInstance.java:358)
> at net.jini.io.MarshalledInstance.get(MarshalledInstance.java:287)
> at com.sun.jini.proxy.MarshalledWrapper.get(MarshalledWrapper.java:127)
> at com.sun.jini.reggie.Item.get(Item.java:141)
> at com.sun.jini.reggie.Item.toServiceItem(Item.java:177)
> at com.sun.jini.reggie.Matches.get(Matches.java:62)
> at com.sun.jini.reggie.RegistrarProxy.lookup(RegistrarProxy.java:128)
> at net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl$LookupTask.run(ServiceDiscoveryManager.java:929)
> at net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl$RegisterListenerTask.run(ServiceDiscoveryManager.java:901)
> at com.sun.jini.thread.TaskManager$TaskThread.run(TaskManager.java:331)
>
> Everything works fine when I have:
> grant {
> java.security.AllPermission;
> }
> in my policy file.
>
> I don't know how to solve it but shouldn't PreferredClassProvider
> load classes and proxy classess inside
> AccessController.doPrivileged() ? I don't think it is
> WebappClassloader bug - it has to check permissions so that it is
> impossible for one web application to load classes from another web
> application.
>
> What do you think?
With the disclaimer that I'm no Tomcat expert, I think that its
WebappClassloader should execute the specialized piece of its
findClass override within a doPrivileged block that restores some
previous (consistent) access control context, for the same reason that
its superclass java.net.URLClassLoader's findClass does the same
thing: because lazy class loading can be triggered when there are
arbitrary restricted protection domains on the stack. If your servlet
had explicitly loaded the interfaces (and any other dependent types)
first-- like reflectively using Class.forName-- I suspect that this
access control exception would not occur, because the loadClass
invocation would be satisfied through the loaded class cache and never
get to findClass. But these permission requirements should not depend
on such order of operations.
(As far as one web application being able to load classes from
another, it would presumably need a reference to the other's class
loader, which should not be available without a permission check.)
This seems similar to the following bug that was filed against Tomcat
5.0.19:
http://issues.apache.org/bugzilla/show_bug.cgi?id=28256
by the author of the jiniservlet project[1]. It appears to have been
closed as not "relevant" given some planned refactoring, but as far as
I can tell the described issue still applies to the 6.0.14 version's
WebappClassloader.
-- Peter
[1] https://jiniservlet.dev.java.net/
--------------------------------------------------------------------------
Getting Started: http://www.jini.org/wiki/Category:Getting_Started
Community Web Site: http://jini.org
jini-users Archive: http://archives.java.sun.com/archives/jini-users.html
Unsubscribing: email "signoff JINI-USERS" to [email protected]