geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jarek Gawor <jga...@gmail.com>
Subject Re: JDK 7 Classloading Behavior Change
Date Tue, 09 Jul 2013 14:44:00 GMT
Does this work ok if the "org.osgi.framework.bundle.parent" property
is set to "framework"? I would think so but would like to get
confirmation. This property is set to "framework" in Karaf so I would
prefer to go with that. If the property is not set, it defaults to
"boot" (the boot classloader) which kind of explains the problem.

Jarek



On Wed, Jul 3, 2013 at 12:38 PM, Andy McCright
<j.andrew.mccright@gmail.com> 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

Mime
View raw message