Another two options: 4) Update the JAVA_OPTS in the geronimo scripts to include: -Xbootclasspath/a:$JAVA_HOME/jre/lib/ext/javascript.jar # linux -Xbootclasspath/a:%JAVA_HOME%\jre\lib\ext\javascript.jar # windows
This is only used on the IBM JDK and has the effect of appending the javascript.jar to the boot classloader's classpath - essentially reverting the JDK change. I'd like to hear more about why the JDK changed before using this option, but it might be more convenient. 5) Do nothing - or maybe just document that if users see this issue on Java 7, that they should add the "osgi.parentClassloader=ext" line to their system.properties file. Thanks, Andy On Wed, Jul 3, 2013 at 11:38 AM, Andy McCright <[email protected]>wrote: > Hi All, > > I have noticed that IBM has changed the classloader used to load com.sun.* > (specifically com.sun.script.javascript) classes in JDK 7. In JDK 6, these > classes were loaded by the JVM's boot classloader - in JDK 7, they are > loaded via the JVM's ext classloader (a child classloader of the boot > loader). This change has the effect of breaking servlet code like this: > > > ScriptEngineManager manager = new ScriptEngineManager(); > ScriptEngine engine = manager.getEngineByName("JavaScript"); > if(engine == null) { > throw new RuntimeException("Oh no, unable to find a script > engine found for JavaScript"); > } > > When running Geronimo 3.0.1 on JDK 6, this code works (engine is non-null, > no exception is thrown). When I switch to JDK7, I see: > ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: > Provider com.sun.script.javascript.RhinoScriptEngineFactory not found > java.lang.RuntimeException: Oh no, unable to find a script engine found > for JavaScript > at org.apache.jsp.HelloWorld_jsp._jspService(HelloWorld_jsp.java:96) > at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:668) > at > org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432) > at > org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390) > at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:668) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) > at > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) > at > org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) > at > org.apache.geronimo.tomcat.GeronimoStandardContext$SystemMethodValve.invoke(GeronimoStandardContext.java:731) > at > org.apache.geronimo.tomcat.valve.GeronimoBeforeAfterValve.invoke(GeronimoBeforeAfterValve.java:48) > at > org.apache.geronimo.tomcat.valve.ProtectedTargetValve.invoke(ProtectedTargetValve.java:53) > at > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) > at > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) > at > org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947) > at > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) > at > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) > at > org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009) > at > org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) > at > org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) > at org.apache.geronimo.pool.ThreadPool$1.run(ThreadPool.java:267) > at > org.apache.geronimo.pool.ThreadPool$ContextClassLoaderRunnable.run(ThreadPool.java:397) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) > at java.lang.Thread.run(Thread.java:769) > > The reason this fails is that the bundle's classloader's parent loader is > the JVM's boot classloader, not the ext loader - so it cannot load the > com.sun.* classes that it needs (and that it could in JDK6). > > One solution to this is to add the following line to > <geronimo_home>/etc/system.properties: > osgi.parentClassloader=ext > > This forces the bundle's to search the ext loader (in addition to the boot > loader) on boot delegated loads. > > I'm wondering if there should be a more permanent fix... here are a few > suggestions: > 1) Work with the JDK teams to revert back to the old behavior - I have a > ticket open with JDK support, but they apparently moved the com.sun.* > classes to the ext loader for a security issue, so it may be a hard sell to > get them to move it back. > 2) Update the default system.properties to include > osgi.parentClassloader=ext > 3) Modify the ClassLoaderHook's getBundleClassLoaderParent() method to > return the ext loader ( ClassLoader.getSystemClassLoader().getParent() ). > > If #1 is not an option, then I think I like optino #2 better than #3, as > it allows users to change it easily if they want a different behavior. > > Does anybody have strong opinions? Or other suggestions? > > Thanks, Andy >
