Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 430450

Summary: Add Java 8 support by disabling ClassReader for FileInputStreams during web app initialization
Product: [RT] Jetty Reporter: Alexander Orlov <alexander.orlov>
Component: otherAssignee: Jan Bartel <janb>
Status: CLOSED INVALID QA Contact:
Severity: blocker    
Priority: P3 CC: janb, jetty-inbox
Version: 9.1.3   
Target Milestone: 9.1.x   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
add Java 8 support by disabling ClassReader for FileInputStreams during web app initialization
none
test webapp project
none
log of output from test webapp run from a jetty distribution with asm5 none

Description Alexander Orlov CLA 2014-03-15 11:47:01 EDT
Created attachment 240927 [details]
add Java 8 support by disabling ClassReader for FileInputStreams during web app initialization

When I launch a Java8 / JDK8 web app using

java -jar target/dependency/jetty-runner.jar  target/*.war

I get

##########
idea:~/my/project/hybris/order-service feature/KIWIS-45 java -jar target/dependency/jetty-runner.jar  target/*.war
2014-03-15 00:42:00.107:INFO::main: Logging initialized @186ms
2014-03-15 00:42:00.117:INFO:oejr.Runner:main: Runner
2014-03-15 00:42:00.240:INFO:oejs.Server:main: jetty-9.1.4-SNAPSHOT
2014-03-15 00:42:02.594:WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.w.WebAppContext@445b84c0{/,file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT/,STARTING}{file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT.war}
MultiException[java.lang.RuntimeException: Error scanning file RepositoryClient$1.class, java.lang.RuntimeException: Error scanning file RepositoryClient$2.class, java.lang.RuntimeException: Error scanning file RepositoryClient.class]
	at org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:530)
	at org.eclipse.jetty.annotations.AnnotationConfiguration.configure(AnnotationConfiguration.java:441)
	at org.eclipse.jetty.webapp.WebAppContext.configure(WebAppContext.java:467)
	at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1343)
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:745)
	at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:493)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:117)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:99)
	at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:154)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:117)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:99)
	at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:117)
	at org.eclipse.jetty.server.Server.start(Server.java:358)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:99)
	at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
	at org.eclipse.jetty.server.Server.doStart(Server.java:325)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.runner.Runner.run(Runner.java:509)
	at org.eclipse.jetty.runner.Runner.main(Runner.java:557)
2014-03-15 00:42:02.595:WARN:oejsh.RequestLogHandler:main: !RequestLog
2014-03-15 00:42:02.618:INFO:oejs.ServerConnector:main: Started ServerConnector@548a9f61{HTTP/1.1}{0.0.0.0:8080}
2014-03-15 00:42:02.619:INFO:oejs.Server:main: Started @2703ms
^C2014-03-15 00:42:11.246:INFO:oejs.ServerConnector:Thread-0: Stopped ServerConnector@548a9f61{HTTP/1.1}{0.0.0.0:8080}
2014-03-15 00:42:11.247:INFO:oejsh.ContextHandler:Thread-0: Stopped o.e.j.w.WebAppContext@445b84c0{/,file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT/,UNAVAILABLE}{file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT.war}
idea:~/my/project/hybris/order-service feature/KIWIS-45 
###########

because org.objectweb.asm.ClassReader is constructed with a FileInputStream which it does not support. Attached is a patch to resolved this Java8 related blocker issue.
Comment 1 Alexander Orlov CLA 2014-03-15 12:39:25 EDT
Afterwards everything went well:

###########
idea:~/my/project/hybris/order-service feature/KIWIS-45 java -jar target/dependency/jetty-runner.jar  target/*.war
2014-03-15 17:39:02.777:INFO::main: Logging initialized @116ms
2014-03-15 17:39:02.786:INFO:oejr.Runner:main: Runner
2014-03-15 17:39:02.867:INFO:oejs.Server:main: jetty-9.1.4-SNAPSHOT
2014-03-15 17:39:04.821:INFO:/:main: Spring WebApplicationInitializers detected on classpath: [org.glassfish.jersey.server.spring.SpringWebApplicationInitializer@5c072e3f]
2014-03-15 17:39:04.990:INFO:/:main: Initializing Spring root WebApplicationContext
2014-03-15 17:39:05,367 [INFO ][main][com.hybris.caas.order.client.RepositoryClient][][] Repository service URL: http://repository-dprod.deis-dev-01.ytech.fra.hybris.com
2014-03-15 17:39:05.854:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@445b84c0{/,file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT/,AVAILABLE}{file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT.war}
2014-03-15 17:39:05.855:WARN:oejsh.RequestLogHandler:main: !RequestLog
2014-03-15 17:39:05.866:INFO:oejs.ServerConnector:main: Started ServerConnector@1b39fd82{HTTP/1.1}{0.0.0.0:8080}
2014-03-15 17:39:05.867:INFO:oejs.Server:main: Started @3209ms
^C2014-03-15 17:39:12.647:INFO:oejs.ServerConnector:Thread-0: Stopped ServerConnector@1b39fd82{HTTP/1.1}{0.0.0.0:8080}
2014-03-15 17:39:12.650:INFO:/:Thread-0: Closing Spring root WebApplicationContext
2014-03-15 17:39:12.653:INFO:oejsh.ContextHandler:Thread-0: Stopped o.e.j.w.WebAppContext@445b84c0{/,file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT/,UNAVAILABLE}{file:/Users/alex/my/project/hybris/order-service/target/order-service-web-1.0.3-SNAPSHOT.war}
idea:~/my/project/hybris/order-service feature/KIWIS-45 
###############
Comment 2 Jan Bartel CLA 2014-03-16 20:25:42 EDT
Alexander,

Is this something that would be fixed by moving to ASM 5.0 for JDK 8?

See https://bugs.eclipse.org/bugs/show_bug.cgi?id=419801

Jan
Comment 3 Alexander Orlov CLA 2014-03-16 20:29:03 EDT
Hi Jan,

Unfortunately not. I've tried explicitly setting ASM lib version to 5_BETA in jetty-annotation's pom.xml — without any change.

Cheers,
Alex
Comment 4 Jan Bartel CLA 2014-03-16 20:55:56 EDT
Alexander,

So just to be sure I understand this, to reproduce the problem the only necessary steps are:

+ use an archived .war file containing WEB-INF/lib jar files (or is WEB-INF/classes the problem ???)
+ use jdk 8

thanks
Jan
Comment 5 Alexander Orlov CLA 2014-03-16 21:14:19 EDT
The problem is "target/order-service-web-1.0.3-SNAPSHOT/WEB-INF/classes/" which is essentially part of the WAR. As I'm not using any exotic webapp config, I also assume you have to use JDK8. I cannot use JDK7 to test, as my code base relies on Java8 language features.

A MultiException was added (thrown at the place I've fixed) as the parseDir was going through my order-service-web-1.0.3-SNAPSHOT/WEB-INF/classes/ folder and reading its classes.

Alex
Comment 6 Alexander Orlov CLA 2014-03-16 21:14:59 EDT
/lib/*.jar was not the problem.
Comment 7 Jan Bartel CLA 2014-03-17 00:11:57 EDT
Alexander,

I haven't been able to reproduce the problem.

I'm using jetty-runner 9.1.4 SNAPSHOT (ie HEAD), and the latest JDK1.8 build 1.8.0-b132 with the test-spec webapp from the jetty-distribution.

Can you attach a small webapp that demonstrates the problem?

thanks
Jan
Comment 8 Alexander Orlov CLA 2014-03-17 07:04:12 EDT
Unfortunately I cannot run /tests/test-webapps/test-servlet-spec. I get
#########
[ERROR] No plugin found for prefix 'jetty' in the current project and in the plugin groups [de.hybris.mavenplugins, org.codehaus.cargo, de.hybris.platform, com.sap.research, org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/alex/.m2/repository), central (http://repo1.maven.org/maven2), hybris-repository (http://repository.hybris.com/hybris-repository)] -> [Help 1]
[ERROR] 
#########

In respect to my app, I'm not allowed to share its source code and cannot provide you with a stripped down version because of time issues.

I've tested this issue with the same config you've mentioned. The problem is that ClassReader does not support and FileInputStream. You can mock a FileInputStream to validate this case. 9.0.7.v20131107 is the last version that works with my setup.
Comment 9 Jan Bartel CLA 2014-03-17 21:14:46 EDT
Alexander,

The webapp I'm referring to is another level down:

tests/test-webapps/test-servlet-spec/test-spec-webapp

I'm dubious that a FileInputStream is not supported - surely the .class files inside an unpacked webapp would all be represented for reading as FileInputStreams??


Also, have you deployed your webapp into a normal jetty distribution, and if so, does it work?

thanks
Jan


(In reply to Alexander Orlov from comment #8)
> Unfortunately I cannot run /tests/test-webapps/test-servlet-spec. I get
> #########
> [ERROR] No plugin found for prefix 'jetty' in the current project and in the
> plugin groups [de.hybris.mavenplugins, org.codehaus.cargo,
> de.hybris.platform, com.sap.research, org.apache.maven.plugins,
> org.codehaus.mojo] available from the repositories [local
> (/Users/alex/.m2/repository), central (http://repo1.maven.org/maven2),
> hybris-repository (http://repository.hybris.com/hybris-repository)] -> [Help
> 1]
> [ERROR] 
> #########
> 
> In respect to my app, I'm not allowed to share its source code and cannot
> provide you with a stripped down version because of time issues.
> 
> I've tested this issue with the same config you've mentioned. The problem is
> that ClassReader does not support and FileInputStream. You can mock a
> FileInputStream to validate this case. 9.0.7.v20131107 is the last version
> that works with my setup.
Comment 10 Jan Bartel CLA 2014-03-17 21:29:22 EDT
Also, I'd like to see the log with -Dorg.eclipse.jetty.annotations.LEVEL=DEBUG - that should print out something for every class that is scanned.

thanks
Jan
Comment 11 Alexander Orlov CLA 2014-03-18 03:12:16 EDT
I already did it preparing the patch. Except a few 
##########
2014-03-18 08:03:08.140:DBUG:oeja.AnnotationParser:qtp1867083167-15: Not a class: 
about.html
##########

You're right FileInputStream is an InputStream and hence should be accepted by ClassReader. But in fact the ASM lib is doing some analysis to assure compatibility. In fact 5.0_BETA is mentioning an 1.8 Opcode constant. Nevertheless ASM's ClassReader throws an IllegalArgumentException trying to deal with some/all(?) FileInputStreams. I guess this issue will gain severity once Java 8 is released this week.
Comment 12 Alexander Orlov CLA 2014-03-18 03:12:55 EDT
I already did it preparing the patch. Except a few 
##########
2014-03-18 08:03:08.140:DBUG:oeja.AnnotationParser:qtp1867083167-15: Not a class: 
about.html
##########

I  do not see anything special there.
Comment 13 Jan Bartel CLA 2014-03-18 03:23:37 EDT
Hi Alexander,

I just haven't been able to reproduce this at all with jdk1.8 and the test webapp that I know contains WEB-INF/classes and WEB-INF/lib jars and indeed has annotations that need to be scanned.

Is there any information about your setup that you can give me at all that would help to reproduce?

cheers
Jan
Comment 14 Alexander Orlov CLA 2014-03-18 03:40:37 EDT
I'm using the latest Jersey 2.7, Spring 4.0.2_RELEASE, jersey-spring3 v2.7. These are the specifics. Also I have to use a super POM but I think I override almost everything it provides.
Comment 15 Alexander Orlov CLA 2014-03-18 11:55:43 EDT
The ASM libs makes the life a lot more difficult. Using Java 8 language constructs (e.g. closures) results in:

java.lang.ArrayIndexOutOfBoundsException: 71345
	at org.objectweb.asm.ClassReader.<init>(Unknown Source)

I know this could be filed as a separate issue but the entire library is not Java8 compliant in a lot of places.
Comment 16 Jan Bartel CLA 2014-03-19 04:58:49 EDT
Alexander,

I'm attaching a test webapp I'm using. I've now ensured it compiles as 1.8, and even copied in a class from the jdk documentation that uses lamba closures to ensure that the source is definitely 1.8.  I've also used the same dependencies as you. I've recompiled jetty to use asm 5.0 (ie 5.0 final release) and am using this webapp in the built jetty distribution, using jdk 1.8 (build 1.8.0-b132). I can't reproduce any failures.

 I put some extra debug into the org.eclipse.jetty.annotations.AnnotationParser class to show the class being scanned, and the class of the InputStream matching the bytes - all the classes in WEB-INF/classes use a FileInputStream with no problems.

The only way I can see you getting any errors is if you have asm 4.1 on the classpath, and your classes are compiled for jdk1.8. If you're using the jetty-runner then it has built-in asm 4.1.  If you have modified the jetty-runner pom.xml to use asm-5, make sure you don't have both asm 4.1 and asm 5.0 as dependencies (transitive or otherwise).

I think the next step would be for you to modify this test webapp so that it more closely resembles your setup, and thus reproduce the error.

regards
Jan
Comment 17 Jan Bartel CLA 2014-03-19 05:01:24 EDT
Created attachment 240996 [details]
test webapp project
Comment 18 Jan Bartel CLA 2014-03-19 05:03:11 EDT
Created attachment 240997 [details]
log of output from test webapp run from a jetty distribution with asm5
Comment 19 Alexander Orlov CLA 2014-03-19 13:35:18 EDT
Thanks Jan.

Some of the XMLs in your sample app are completely corrupted. I've fixed them but I keep another, not related exception:

#########
[INFO] Webapp directory = /Users/alex/Downloads/bug-430450/src/main/webapp
2014-03-19 18:31:52.483:INFO:oejs.Server:jetty-8.1.14.v20131031
2014-03-19 18:31:52.857:WARN:oejx.XmlConfiguration:Config error at <New id="maxAmount" class="org.eclipse.jetty.plus.jndi.EnvEntry"><Arg><Ref refid="wac"/></Arg><Arg>maxAmount</Arg><Arg type="java.lang.Double">55.0</Arg><Arg type="boolean">true</Arg></New> java.lang.IllegalStateException: No object for id=null
2014-03-19 18:31:52.858:WARN:oejw.WebAppContext:Failed startup of context o.m.j.p.JettyWebAppContext{/,[file:/Users/alex/Downloads/bug-430450/src/main/webapp/, jar:file:/Users/alex/.m2/repository/org/eclipse/jetty/tests/test-web-fragment/9.1.4-SNAPSHOT/test-web-fragment-9.1.4-SNAPSHOT.jar!/META-INF/resources/]},file:/Users/alex/Downloads/bug-430450/src/main/webapp/
java.lang.IllegalStateException: No object for id=null
	at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.refObj(XmlConfiguration.java:846)

#########

Looks like an XML config issue. Also on which platform are you running JDK8? I'm on a Mac.
Comment 20 Alexander Orlov CLA 2014-03-19 14:04:39 EDT
Ok. Finally. After updating the ASM libs in *all* POMs to 5.0, the app run flawless *without* my patch. So bring your patched version to the people asap please :)
Comment 21 Jan Bartel CLA 2014-03-24 00:01:10 EDT
Hi Alexander,

OK, good. I'll close this issue as we have another issue open for upgrading to asm-5 here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=419801

cheers
Jan