Tuesday 5 January 2010

RESTlet deployment woes (from GlassFish v2 to AppServer v2)

Some incomplete notes on deploying our RESTlet-based application (tested on GlassFish) to our Sun AppServer v2.1.

Deployed then had exception in the logs:
PWC1382: Allocate exception for servlet Servlet java.lang.ExceptionInInitializerError
 at org.restlet.Restlet.(Restlet.java:99)
 at org.restlet.Application.(Application.java:147)
 at org.restlet.Application.(Application.java:134)
 at com.maldenlabs.server.config.restlet.ConfigApplication.(ConfigApplication.java:21)
 at com.maldenlabs.server.config.restlet.ConfigApplication.(ConfigApplication.java:17)
 at com.maldenlabs.server.config.restlet.jee.Servlet.init(Servlet.java:34)
 at javax.servlet.GenericServlet.init(GenericServlet.java:270)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:292)
 at java.security.AccessController.doPrivileged(Native Method)
 at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
 at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:325)
 at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:208)
 at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:161)
 at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1188)
 at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:848)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
 at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
 at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
 at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
 at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
 at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
 at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288)
 at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647)
 at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579)
 at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831)
 at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
 at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
 at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
 at com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask(PortUnificationPipeline.java:380)
 at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
 at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106) Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission createClassLoader)
 at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
 at java.security.AccessController.checkPermission(AccessController.java:546)
 at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
 at java.lang.SecurityManager.checkCreateClassLoader(SecurityManager.java:594)
 at java.lang.ClassLoader.(ClassLoader.java:202)
 at org.restlet.engine.util.EngineClassLoader.(EngineClassLoader.java:55)
 at org.restlet.engine.Engine.(Engine.java:57) ... 46 more

Answer 1 found:
http://forums.java.net/jive/message.jspa?messageID=215402#215402
One needs to grant the "createClassLoader" permissions to the app in the domain's server.policy file.
Specifically, to the file /opt/SUNWappserver/domains/domain1/config/server.policy, append:
// Permissions for ConfigServer
grant codeBase "file:${com.sun.aas.instanceRoot}/applications/j2ee-apps/config" {
    permission java.lang.RuntimePermission "createClassLoader";
};

Restarting the instance, now see
PWC1382: Allocate exception for servlet Servlet java.lang.NoClassDefFoundError: Could not initialize class org.restlet.engine.Engine
 at org.restlet.Restlet.(Restlet.java:99)
 at org.restlet.Application.(Application.java:147)
 at org.restlet.Application.(Application.java:134)
 at com.maldenlabs.server.config.restlet.ConfigApplication.(ConfigApplication.java:21)
 at com.maldenlabs.server.config.restlet.ConfigApplication.(ConfigApplication.java:17)
 at com.maldenlabs.server.config.restlet.jee.Servlet.init(Servlet.java:34)
 at javax.servlet.GenericServlet.init(GenericServlet.java:270)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:292)
 at java.security.AccessController.doPrivileged(Native Method)
 at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
 at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:325)
 at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:208)
 at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:161)
 at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1188)
 at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:848)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
 at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
 at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
 at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
 at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
 at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
 at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
 at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288)
 at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647)
 at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579)
 at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831)
 at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
 at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
 at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
 at com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask(PortUnificationPipeline.java:380)
 at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
 at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)

NoClassDefFoundError = dependency problem (A cannot initialize because it uses B which cannot be loaded).  My favourite explanation is here.  For us, Restlet is failing to construct (i.e. <init>) because Engine is failing to load.

For confirmation, built a test project with dependencies Main.main -> ARequiresDepB.<init> -> BDependency, ran from jar fine, removed BDependency.class from jar and re-ran:
Exception in thread "main" java.lang.NoClassDefFoundError: a/b/c/BDependency
        at a.b.c.ARequiresDepB.(ARequiresDepB.java:13)
        at a.b.c.Main.main(Main.java:10)
Caused by: java.lang.ClassNotFoundException: a.b.c.BDependency
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        ... 2 more

So the class named after NCDFE is the missing class that was required for the class named on the next line. (n.b. this constructor was setting into an instance variable.)
Checking the EAR that contains the WAR, it contains the "WEB-INF/lib" that contains "org.restlet.jar" which contains "org/restlet/engine/Engine.class".
Continuing to investigate...

UPDATE: I know we solved this. Sorry I never blogged it at the time :-(

No comments:

Post a Comment