8 Replies Latest reply on Aug 11, 2006 3:04 AM by renat-zubairov

    AccessControlException on generated classes due to missing

    renat-zubairov

      I have a problem with Tapestry/HiveMind application which uses Javassist for bytecode manipulation. It seems that newly created classes that are loaded by Javassist do not inherit ProtectionDomain from the other classes, this leads to the problem that application server WebSphere can not associate them with any of the JAR files and apply a security policy to them. The problem is visible on the following stack trace, you can see that location of the code that causes security exception is unknown (null).

      Environment is WebSphere 5 with Secruty ON (Enforce Java2 Security):



      [7/15/06 15:22:41:049 CEST] 6642251f SecurityManag W SECJ0314W: Current Java 2 Security policy reported a potential violation of Java 2 Security Permission.
      Please refer to Problem Determination Guide for further information.

      Permission:

      /opt/WebSphere/AppServer/installedApps/servernameNetwork/sjrthr.ear/sjrtpg.war/WEB-INF/lib/tapestry-4.1.jar : access denied (java.io.FilePermission /opt/We
      bSphere/AppServer/installedApps/servernameNetwork/sjrthr.ear/sjrtpg.war/WEB-INF/lib/tapestry-4.1.jar read)


      Code:

      $ApplicationInitializer_10c725a4dba in {null code URL}



      Stack Trace:

      java.security.AccessControlException: access denied (java.io.FilePermission /opt/WebSphere/AppServer/installedApps/servernameNetwork/sjrthr.ear/sjrtpg.war/WEB-IN
      F/lib/tapestry-4.1.jar read)
      at java.security.AccessControlContext.checkPermission(AccessControlContext.java(Compiled Code))
      at java.security.AccessController.checkPermission(AccessController.java(Compiled Code))
      at java.lang.SecurityManager.checkPermission(SecurityManager.java(Compiled Code))
      at com.ibm.ws.security.core.SecurityManager.checkPermission(SecurityManager.java(Compiled Code))
      at java.lang.SecurityManager.checkRead(SecurityManager.java(Compiled Code))
      at java.util.zip.ZipFile.(ZipFile.java(Compiled Code))
      at java.util.zip.ZipFile.(ZipFile.java(Inlined Compiled Code))
      at com.ibm.ws.classloader.Handler$ClassLoaderURLConnection.getInputStream(Handler.java(Compiled Code))
      at java.net.URL.openStream(URL.java(Inlined Compiled Code))
      at com.ibm.ws.classloader.SinglePathClassProvider.getResourceAsStream(SinglePathClassProvider.java(Inlined Compiled Code))
      at com.ibm.ws.classloader.CompoundClassLoader.localGetResourceAsStream(CompoundClassLoader.java(Compiled Code))
      at com.ibm.ws.classloader.CompoundClassLoader.getResourceAsStream(CompoundClassLoader.java(Compiled Code))
      at javassist.LoaderClassPath.openClassfile(LoaderClassPath.java:70)
      at javassist.ClassPoolTail.openClassfile(ClassPoolTail.java:283)
      at javassist.ClassPool.openClassfile(ClassPool.java(Inlined Compiled Code))
      at javassist.CtClassType.getClassFile2(CtClassType.java(Compiled Code))
      at javassist.CtClassType.subtypeOf(CtClassType.java:267)
      at javassist.compiler.MemberResolver.compareSignature(MemberResolver.java:203)
      at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:97)
      at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:637)
      at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:614)
      at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)
      at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
      at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:235)
      at javassist.compiler.CodeGen.atStmnt(CodeGen.java:323)
      at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
      at javassist.compiler.CodeGen.atIfStmnt(CodeGen.java:384)
      at javassist.compiler.CodeGen.atStmnt(CodeGen.java:348)
      at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
      at javassist.compiler.CodeGen.atStmnt(CodeGen.java:344)
      at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
      at javassist.compiler.CodeGen.atMethodBody(CodeGen.java:285)
      at javassist.compiler.Javac.compileBody(Javac.java:208)
      at javassist.CtBehavior.setBody(CtBehavior.java:188)
      at javassist.CtBehavior.setBody(CtBehavior.java:163)
      at org.apache.hivemind.service.impl.ClassFabImpl.addMethod(ClassFabImpl.java:288)
      at org.apache.hivemind.service.impl.LoggingInterceptorFactory.addServiceMethodImplementation(LoggingInterceptorFactory.java:120)
      at org.apache.hivemind.service.impl.LoggingInterceptorFactory.addServiceMethods(LoggingInterceptorFactory.java:159)
      at org.apache.hivemind.service.impl.LoggingInterceptorFactory.constructInterceptorClass(LoggingInterceptorFactory.java:214)
      at org.apache.hivemind.service.impl.LoggingInterceptorFactory.createInterceptor(LoggingInterceptorFactory.java:251)
      at org.apache.hivemind.impl.ServiceInterceptorContributionImpl.createInterceptor(ServiceInterceptorContributionImpl.java:95)
      at org.apache.hivemind.impl.InterceptorStackImpl.process(InterceptorStackImpl.java:116)
      at org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl.addInterceptors(AbstractServiceModelImpl.java:85)
      at org.apache.hivemind.impl.servicemodel.PooledServiceModel.constructServiceProxy(PooledServiceModel.java:154)
      at org.apache.hivemind.impl.servicemodel.PooledServiceModel.(PooledServiceModel.java:130)
      at org.apache.hivemind.impl.servicemodel.PooledServiceModelFactory.createServiceModelForService(PooledServiceModelFactory.java:26)
      at org.apache.hivemind.impl.ServicePointImpl.getService(ServicePointImpl.java:208)
      at org.apache.hivemind.impl.ServicePointImpl.getService(ServicePointImpl.java:223)
      at org.apache.hivemind.impl.RegistryInfrastructureImpl.getService(RegistryInfrastructureImpl.java:207)
      at org.apache.hivemind.impl.ModuleImpl.getService(ModuleImpl.java:105)
      at org.apache.hivemind.schema.rules.ServiceTranslator.translate(ServiceTranslator.java:40)
      at org.apache.hivemind.service.impl.BuilderPropertyFacet.getFacetValue(BuilderPropertyFacet.java:55)
      at org.apache.hivemind.service.impl.BuilderFactoryLogic.wireProperty(BuilderFactoryLogic.java:357)
      at org.apache.hivemind.service.impl.BuilderFactoryLogic.setProperties(BuilderFactoryLogic.java:320)
      at org.apache.hivemind.service.impl.BuilderFactoryLogic.createService(BuilderFactoryLogic.java:77)
      at org.apache.hivemind.service.impl.BuilderFactory.createCoreServiceImplementation(BuilderFactory.java:42)
      at org.apache.hivemind.impl.InvokeFactoryServiceConstructor.constructCoreServiceImplementation(InvokeFactoryServiceConstructor.java:62)
      at org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl.constructCoreServiceImplementation(AbstractServiceModelImpl.java:108)
      at org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl.constructNewServiceImplementation(AbstractServiceModelImpl.java:158)
      at org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl.constructServiceImplementation(AbstractServiceModelImpl.java:140)
      at org.apache.hivemind.impl.servicemodel.SingletonServiceModel.getActualServiceImplementation(SingletonServiceModel.java:69)
      at $ApplicationInitializer_10c725a4dba._service($ApplicationInitializer_10c725a4dba.java)
      at $ApplicationInitializer_10c725a4dba.initialize($ApplicationInitializer_10c725a4dba.java)
      at $ApplicationInitializer_10c725a4db9.initialize($ApplicationInitializer_10c725a4db9.java)
      at $ApplicationInitializer_10c725a4dbd.initialize($ApplicationInitializer_10c725a4dbd.java)
      at $ApplicationInitializer_10c725a4db2.initialize($ApplicationInitializer_10c725a4db2.java)
      at $ApplicationInitializer_10c725a4db1.initialize($ApplicationInitializer_10c725a4db1.java)
      at org.apache.tapestry.ApplicationServlet.initializeApplication(ApplicationServlet.java:299)
      at org.apache.tapestry.ApplicationServlet.init(ApplicationServlet.java:198)
      at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doInit(StrictServletInstance.java:82)
      at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._init(StrictLifecycleServlet.java:147)
      at com.ibm.ws.webcontainer.servlet.PreInitializedServletState.init(StrictLifecycleServlet.java:270)
      at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.init(StrictLifecycleServlet.java:113)
      at com.ibm.ws.webcontainer.servlet.ServletInstance.init(ServletInstance.java:189)
      at javax.servlet.GenericServlet.init(GenericServlet.java:258)
      ...

        • 1. Re: AccessControlException on generated classes due to missi
          jkuhnert

          If anyone from jboss knows how I can fix this in a more permanent manner in Tapestry 4.1 itself let me know.

          • 2. Re: AccessControlException on generated classes due to missi
            renat-zubairov

            Hi,

            I found a way to fix it, however there are two problems:

            1. I need to commit it somehow, but Jirra from Javassist is seems to be not mantained (vacation time?). As soon as I'll recieve a reasonable answer from someone from Javassist I'll do so.
            2. The changes most problably will affect a public interfaces of the Javassist, because basically the code that is generated from Javassist should not belong to the codebase of the Javassist itself, but rather to the code base of the application that trigger the generation, therefore there is a clear need not to use no-argument classloading but pass a ProtectionDomain to it, therefore respective changes needed to be done in the Hivemind (and not sure about it may be in Tapestry, allthought I haven't seen any direct ussage of the Javassist in Tapestry yet).

            • 3. Re: AccessControlException on generated classes due to missi
              chiba

              Basically, Javassist provides a byte stream of a modified class file. How it is loaded is the responsiblity of the clients such as HiveMind. Although Javassist provides a covenient function for loading it by a simple class loader, the clients should use their own class loaders if they need some application-specific requirements.

              Do you know how HiveMind load classes generated by Javassist?

              Thanks!

              • 4. Re: AccessControlException on generated classes due to missi
                renat-zubairov

                ---- Copy from commen on JIRRA http://jira.jboss.com/jira/browse/JASSIST-23 ----
                Actually HiveMind is using convinience methods that are located inside CtClass class. I have fixed the problem already, and testted how it works, however the problem I don't know what will be the best solution for the problem, there is several alternatives:
                1. Let the client decide which ProtectionDomain should be used during the classloading - make this decision mandatory for all clients
                2. Let clients decide wherever they want to have a new classes associated with ProtectionDomain or not - potential securty problem
                3. Associate all classes loaded by the Javassist with the Javassist protection domain

                I would prefer to declare old method as deprecated, and declare additional method with ProtectionDomain as parameter, then clients can decide which protection domain they want to use.

                P.S. As soon you will decide I can submit this fix either directly to SCV or as patch file and trigger changes in the Hivemind project

                • 5. Re: AccessControlException on generated classes due to missi
                  paul.homes

                  Hi,

                  Thanks for all the info in this thread and making the javassist CVS changes. This really helped me to get a Tapestry & Hivemind web app running in Tomcat with the security manager enabled.

                  I have a question about the default ProtectionDomain when none is specified (currently null). In order to get my app to run I patched the latest Javassist from CVS so that in the ClassPool toClass(CtClass ct, ClassLoader loader) method it uses:

                  return toClass(ct, loader, ct.getClass().getProtectionDomain());

                  .. rather than ..

                  return toClass(ct, loader, null);

                  This works as a better default ProtectionDomain for me, but I was not sure if it would be unsuitable for others. I am happy to use a patched version until such time as HiveMind passes a ProtectionDomain, but if this default were suitable enough to make it into a future version of Javassist then that would be even better :)

                  Cheers
                  Paul

                  • 6. Re: AccessControlException on generated classes due to missi
                    renat-zubairov

                    Hello Paul,

                    It was also my first solution aswell, but the problem is that ProtectionDomain establish association between executed code and resource the code was loaded from, if protection domain from the Javassist is used, then all code generated by the Javassist will be associated with it's protection domain, this is however not a best idea because most probably generated code should be associated with the protection domain of the Javassist client rather than Javassist itself, therefore now I'm trying to submit a change for the Hivemind that Hivemind's ProtectionDomain will be used for all Hivemind generated classes.

                    • 7. Re: AccessControlException on generated classes due to missi
                      paul.homes

                      Hi Renat,

                      Thanks for the clarification. I would be keen to follow the status of your Hivemind update because then I can drop my patch :) Does there happen to be a JIRA issue for it? If so I will add myself as a watcher.

                      Cheers
                      Paul

                      • 8. Re: AccessControlException on generated classes due to missi
                        renat-zubairov

                        Hi

                        Sure, just created:

                        http://issues.apache.org/jira/browse/HIVEMIND-181

                        Watch it, vote for it :)