Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-44870

EOFException with Maven 3.5.0 and Task scanner plugin

      When running a build of Maven project type with Maven 3.5.0 (clean, clean install, ...) and enabled "Scan workspace for open tasks" with Tasks tags FIXME for high priority and TODO for normal priority, we get the following EOFException:

       

      [TASKS] Found 0 files to scan for tasks
       Found 0 open tasks.
       java.io.EOFException
       at java.io.DataInputStream.readInt(DataInputStream.java:392)
       at java.io.ObjectInputStream$BlockDataInputStream.readInt(ObjectInputStream.java:3125)
       at java.io.ObjectInputStream.readInt(ObjectInputStream.java:1023)
       at com.google.common.collect.Serialization.readCount(Serialization.java:50)
       at com.google.common.collect.HashMultimap.readObject(HashMultimap.java:134)
       at sun.reflect.GeneratedMethodAccessor857.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2122)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
       at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2231)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2155)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
       at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2231)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2155)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
       at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1919)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1529)
       at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2231)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2155)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
       at hudson.remoting.UserRequest.deserialize(UserRequest.java:217)
       at hudson.remoting.UserRequest.perform(UserRequest.java:131)
       at hudson.remoting.UserRequest.perform(UserRequest.java:50)
       at hudson.remoting.Request$2.run(Request.java:336)
       at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
       at org.jenkinsci.remoting.CallableDecorator.call(CallableDecorator.java:19)
       at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
       at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
       at java.lang.Thread.run(Thread.java:745)
       at ......remote call to channel(Native Method)
       at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1545)
       at hudson.remoting.UserResponse.retrieve(UserRequest.java:253)
       at hudson.remoting.Channel.call(Channel.java:830)
       at hudson.remoting.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:257)
       at com.sun.proxy.$Proxy5.execute(Unknown Source)
       at hudson.maven.MavenBuildProxy$Filter.execute(MavenBuildProxy.java:207)
       at hudson.plugins.analysis.core.HealthAwareReporter.registerResultsOnMaster(HealthAwareReporter.java:364)
       at hudson.plugins.analysis.core.HealthAwareReporter.postExecute(HealthAwareReporter.java:355)
       at hudson.maven.Maven3Builder$MavenExecutionListener.recordMojoEnded(Maven3Builder.java:629)
       at hudson.maven.Maven3Builder$MavenExecutionListener.mojoSucceeded(Maven3Builder.java:610)
       at hudson.maven.Maven3Builder$JenkinsEventSpy.onEvent(Maven3Builder.java:303)
       at org.apache.maven.eventspy.internal.EventSpyDispatcher.onEvent(EventSpyDispatcher.java:104)
       at org.apache.maven.eventspy.internal.EventSpyExecutionListener.mojoSucceeded(EventSpyExecutionListener.java:131)
       at org.apache.maven.lifecycle.internal.DefaultExecutionEventCatapult.fire(DefaultExecutionEventCatapult.java:87)
       at org.apache.maven.lifecycle.internal.DefaultExecutionEventCatapult.fire(DefaultExecutionEventCatapult.java:42)
       at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
       at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
       at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
       at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
       at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
       at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
       at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
       at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
       at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
       at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
       at org.jvnet.hudson.maven3.launcher.Maven35Launcher.main(Maven35Launcher.java:130)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
       at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
       at jenkins.maven3.agent.Maven35Main.launch(Maven35Main.java:176)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at hudson.maven.Maven3Builder.call(Maven3Builder.java:139)
       at hudson.maven.Maven3Builder.call(Maven3Builder.java:70)
       at hudson.remoting.UserRequest.perform(UserRequest.java:153)
       at hudson.remoting.UserRequest.perform(UserRequest.java:50)
       at hudson.remoting.Request$2.run(Request.java:336)
       at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
       at java.lang.Thread.run(Thread.java:748)

          [JENKINS-44870] EOFException with Maven 3.5.0 and Task scanner plugin

          Ulli Hafner added a comment - - edited

          Thanks for investigating! The field can be made transient without any problems.

          Alternatively, one would need to prevent Maven's Guava classes from being used so that both sides would always use the same Guava version.

          This is not possible with the maven project type, that is one of the reasons why it has the nick name "evil project type". I need to fix class loading bugs nearly with every new maven version But I think in analysis-core 2.0 JENKINS-44957 will be fixed!

          Ulli Hafner added a comment - - edited Thanks for investigating! The field can be made transient without any problems. Alternatively, one would need to prevent Maven's Guava classes from being used so that both sides would always use the same Guava version. This is not possible with the maven project type, that is one of the reasons why it has the nick name "evil project type". I need to fix class loading bugs nearly with every new maven version But I think in analysis-core 2.0 JENKINS-44957 will be fixed!

          Great, looking forward

          Carsten Pfeiffer added a comment - Great, looking forward

          Would it be possible to do a 1.93 release with just this suggested fix (make the field transient)? This is really hurting anyone who wants to move to a newer maven version.

          Henning Schmiedehausen added a comment - Would it be possible to do a 1.93 release with just this suggested fix (make the field transient)? This is really hurting anyone who wants to move to a newer maven version.

          Ulli Hafner added a comment -

          Yes, this would be possible. But there is no PR for the fix yet, or am I missing something? (It is not that easy to just write transient in front of the field. One need to check how to initialize this field correctly.)

          Ulli Hafner added a comment - Yes, this would be possible. But there is no PR for the fix yet, or am I missing something? (It is not that easy to just write transient in front of the field. One need to check how to initialize this field correctly.)

          carpf added a comment -

          Oh, but that's exactly what I did (just adding the transient modifier). The field is initialized on demand when it's null. AFAIU, it works like this:

          • the job is either executed on the master or a slave
          • when finished, the ParserResult object is serialized and deserialized, possibly even over the wire (master/slave scenario)
          • the fileNameCache field, when transient, would be null on the master
          • if that field would be used afterwards, it would be again initialized on demand, by traversing the workspace
          • if the workspace is unavailable on the master, code relying on it would fail  – that's what I meant with "may not work for everyone"

          carpf added a comment - Oh, but that's exactly what I did (just adding the transient modifier). The field is initialized on demand when it's null . AFAIU, it works like this: the job is either executed on the master or a slave when finished, the ParserResult object is serialized and deserialized, possibly even over the wire (master/slave scenario) the fileNameCache field, when transient, would be null  on the master if that field would be used afterwards, it would be again initialized on demand, by traversing the workspace if the workspace is unavailable on the master, code relying on it would fail  – that's what I meant with "may not work for everyone"

          Not sure. In https://github.com/jenkinsci/analysis-core-plugin/blob/master/src/main/java/hudson/plugins/analysis/core/ParserResult.java, the fileNameCache is private final and initialized. So there needs to be logic that deals with it being null (right now, each dereference of the field will throw an NPE after deserialization). I agree it is not hard (add a readObject method that initializes the field to an empty Multimap) but it don't think it is just adding a "transient".

          Henning Schmiedehausen added a comment - Not sure. In https://github.com/jenkinsci/analysis-core-plugin/blob/master/src/main/java/hudson/plugins/analysis/core/ParserResult.java,  the fileNameCache is private final and initialized. So there needs to be logic that deals with it being null (right now, each dereference of the field will throw an NPE after deserialization). I agree it is not hard (add a readObject method that initializes the field to an empty Multimap) but it don't think it is just adding a "transient".

          carpf added a comment -

          Thanks for the link, I didn't have the code at hand. You're right, the lazy initialization doesn't take null into account. This probably means that the code is not called at all after deserialization.

          carpf added a comment - Thanks for the link, I didn't have the code at hand. You're right, the lazy initialization doesn't take null into account. This probably means that the code is not called at all after deserialization.

          Henning Schmiedehausen added a comment - https://github.com/jenkinsci/analysis-core-plugin/pull/84

          Code changed in jenkins
          User: Ulli Hafner
          Path:
          src/main/java/hudson/plugins/analysis/core/ParserResult.java
          http://jenkins-ci.org/commit/analysis-core-plugin/e36b4cfc2f5b02da4be035500b9d220105fd58c6
          Log:
          Merge pull request #84 from hgschmie/JENKINS-44870

          quick fix for deserialization error with fileNameCache

          Compare: https://github.com/jenkinsci/analysis-core-plugin/compare/098f7729a41d...e36b4cfc2f5b

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Ulli Hafner Path: src/main/java/hudson/plugins/analysis/core/ParserResult.java http://jenkins-ci.org/commit/analysis-core-plugin/e36b4cfc2f5b02da4be035500b9d220105fd58c6 Log: Merge pull request #84 from hgschmie/ JENKINS-44870 quick fix for deserialization error with fileNameCache Compare: https://github.com/jenkinsci/analysis-core-plugin/compare/098f7729a41d...e36b4cfc2f5b

          The 1.93 release fixes this problem for me. 

          Henning Schmiedehausen added a comment - The 1.93 release fixes this problem for me. 

            drulli Ulli Hafner
            jochenafuerbacher Jochen A. Fürbacher
            Votes:
            10 Vote for this issue
            Watchers:
            16 Start watching this issue

              Created:
              Updated:
              Resolved: