0 Replies Latest reply on Mar 10, 2011 7:28 AM by Daniel Zeiter

    NoClassDefFoundError during deployment in glassfish 3.1 due to wrong classloader

    Daniel Zeiter Newbie

      We had a problem deploying our EAR wich contained a WAR in Glassfish 3.1 final. It deployed perfectly in Glassfish 3.0.1.


      We got a NullPointerException during deployment wich turned out to be a NoClassDefFoundError when Weld tried to compile a proxy.


      Daemon Thread [admin-thread-pool-4848(5)] (Suspended (exception CannotCompileException))     
           ClassFileUtils.toClass(ClassFile, ClassLoader, ProtectionDomain) line: 117     
           InterceptedSubclassFactory<T>(ProxyFactory<T>).createProxyClass(String) line: 402     
           InterceptedSubclassFactory<T>(ProxyFactory<T>).getProxyClass() line: 283     
           ManagedBean<T>(AbstractClassBean<T>).createEnhancedSubclass() line: 673     
           ManagedBean<T>(AbstractClassBean<T>).initEnhancedSubclass() line: 659     
           ManagedBean<T>(AbstractClassBean<T>).initializeAfterBeanDiscovery() line: 354     
           ManagedBean<T>.initializeAfterBeanDiscovery() line: 420     
           BeanDeployment.doAfterBeanDiscovery(List<Bean<?>>) line: 232     
           BeanDeployment.afterBeanDiscovery(Environment) line: 221     
           WeldBootstrap.deployBeans() line: 369     
           WeldDeployer.event(EventListener$Event) line: 170     
           EventsImpl.send(EventListener$Event, boolean) line: 128     
           EarDeployer$CompositeApplicationInfo(ApplicationInfo).load(ExtendedDeploymentContext, ProgressTracker) line: 262     
           ApplicationLifecycle.deploy(Collection<Sniffer>, ExtendedDeploymentContext) line: 460     
           ApplicationLifecycle.deploy(ExtendedDeploymentContext) line: 240     
           DeployCommand.execute(AdminCommandContext) line: 370     
           CommandRunnerImpl$1.execute(AdminCommandContext) line: 355     
           CommandRunnerImpl.doCommand(CommandModel, AdminCommand, AdminCommandContext) line: 370     
           CommandRunnerImpl.doCommand(CommandRunnerImpl$ExecutionContext, AdminCommand) line: 1067     
           CommandRunnerImpl.access$1200(CommandRunnerImpl, CommandRunnerImpl$ExecutionContext, AdminCommand) line: 96     
           CommandRunnerImpl$ExecutionContext.execute(AdminCommand) line: 1247     
           CommandRunnerImpl$ExecutionContext.execute() line: 1235     
           PublicAdminAdapter(AdminAdapter).doCommand(String, GrizzlyRequest, ActionReport, Payload$Outbound) line: 465     
           PublicAdminAdapter(AdminAdapter).service(GrizzlyRequest, GrizzlyResponse) line: 222     
           PublicAdminAdapter(GrizzlyAdapter).service(Request, Response) line: 168     
           HK2Dispatcher.dispath(Adapter, ClassLoader, Request, Response) line: 117     
           ContainerMapper.service(Request, Response) line: 234     
           ProcessorTask.invokeAdapter() line: 822     
           ProcessorTask.doProcess() line: 719     
           ProcessorTask.process(InputStream, OutputStream) line: 1013     
           DefaultProtocolFilter.execute(Context) line: 225     
           HttpProtocolChain(DefaultProtocolChain).executeProtocolFilter(Context, int) line: 137     
           HttpProtocolChain(DefaultProtocolChain).execute(Context, int) line: 104     
           HttpProtocolChain(DefaultProtocolChain).execute(Context) line: 90     
           HttpProtocolChain.execute(Context) line: 79     
           ProtocolChainContextTask.doCall() line: 54     
           ProtocolChainContextTask(SelectionKeyContextTask).call() line: 59     
           ProtocolChainContextTask(ContextTask).run() line: 71     
           SyncThreadPool$SyncThreadWorker(AbstractThreadPool$Worker).doWork() line: 532     
           SyncThreadPool$SyncThreadWorker(AbstractThreadPool$Worker).run() line: 513     
           HttpWorkerThread(Thread).run() line: 619
      




      We have a web module (war) in the ear and we have libs in the war. All of the above contain BDAs. The problem was that it tried to load a class from the war module with the ear class loader, but it should have used the WebAppClassloader.
      So in the call to ClassFileUtils.toClass(proxyClassType, cl, domain) in the in the method createProxyClass of org.jboss.weld.bean.proxy.ProxyFactory the cl param was the EarClassLoader but it should have been the WebappClassloader. Fortunately ProtectionDomain in the method contains the correct WebappClassloader.


      It seams the method resolveClassLoaderForBeanProxy in org.jboss.weld.bean.proxy.ProxyFactory got the wrong classLoader?


      So we added the following lines before the call to ClassFileUtils.toClass in the createProxyClass method which fixed the issue:



            ClassLoader cl = classLoader;
            if (domain != null) {
                 ClassLoader domainCl = domain.getClassLoader();
                 if (domainCl != null) {
                      cl = domainCl;
                 }
            }





      The funny thing is the error shown above was not thrown consistently. After redeploying the app several times, deployment worked sometimes. With each try to it couldn't find a different class. In theend it could find all classes and deployed. With the above fix the deployment works everytime and the app works perfectly.


      Has anyone experienced similar issues? Is it a Weld bug or a bug in the glassfish 3.1 org.jboss.weld.serialization.spi.ProxyServices implementation? Is there a problem with our ear setup?