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 -

          It is really time to retire the maven plugin So many issues without a workaround...

          Ulli Hafner added a comment - It is really time to retire the maven plugin So many issues without a workaround...

          Adrian Price added a comment -

          I'm seeing this exception with CheckStyle and PMD inspections under Maven-3.5.0 - it doesn't happen under Maven-3.3.9.

          Adrian Price added a comment - I'm seeing this exception with CheckStyle and PMD inspections under Maven-3.5.0 - it doesn't happen under Maven-3.3.9.

          Fabiano Freitas added a comment - - edited

          This error occur when I config the project to publish Checkstyle or PMD analysis results. When I uncheck this option, the error does not occour anymore.

          I used maven 3.5.0 and 3.5.2.

          Fabiano Freitas added a comment - - edited This error occur when I config the project to publish Checkstyle or PMD analysis results. When I uncheck this option, the error does not occour anymore. I used maven 3.5.0 and 3.5.2.

          The cause is the fileNameCache field in hudson.plugins.analysis.core.ParserResult. It's a Guava HashMultimap instance.

          • Maven 3.3.9 bundles Guava 18.
          • Maven 3.5 bundles Guava 19

          These Guava version appear to be incompatible wrt serialization, at least due to this commit (use git diff -r v18.0 -r v19.0 to compare the versions):

          commit a70f009926809b9a37ebbc16ebbc9cf71030be11
          Author: cpovirk <cpovirk@google.com>
          Date: Thu Dec 4 14:01:30 2014 -0800

          Skip unnecessary presizing.
          -------------
          Created by MOE: http://code.google.com/p/moe-java
          MOE_MIGRATED_REVID=81367572

          [...]
          @@ -122,17 +119,15 @@ public final class HashMultimap<K, V> extends AbstractSetMultimap<K, V> {
             @GwtIncompatible("java.io.ObjectOutputStream")
             private void writeObject(ObjectOutputStream stream) throws IOException {
               stream.defaultWriteObject();
          -    stream.writeInt(expectedValuesPerKey);
               Serialization.writeMultimap(this, stream);
             }
          

          The quick hack is to make the fileNameCache field transient in the analysis-core plugin, but this may not work for everyone.

          Carsten Pfeiffer added a comment - The cause is the fileNameCache field in hudson.plugins.analysis.core.ParserResult . It's a Guava HashMultimap instance. Maven 3.3.9 bundles Guava 18. Maven 3.5 bundles Guava 19 These Guava version appear to be incompatible wrt serialization, at least due to this commit (use git diff -r v18.0 -r v19.0 to compare the versions): commit a70f009926809b9a37ebbc16ebbc9cf71030be11 Author: cpovirk <cpovirk@google.com> Date: Thu Dec 4 14:01:30 2014 -0800 Skip unnecessary presizing. ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=81367572 [...] @@ -122,17 +119,15 @@ public final class HashMultimap<K, V> extends AbstractSetMultimap<K, V> { @GwtIncompatible( "java.io.ObjectOutputStream" ) private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); - stream.writeInt(expectedValuesPerKey); Serialization.writeMultimap( this , stream); } The quick hack is to make the fileNameCache field transient in the analysis-core plugin, but this may not work for everyone.

          A more sensible fix would be to use a different (non-Guava) class for the fileNameCache field. The Guava docs explicitly say that serialized objects are not guaranteed to be compatible between Guava versions.

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

          Carsten Pfeiffer added a comment - A more sensible fix would be to use a different (non-Guava) class for the fileNameCache field. The Guava docs explicitly say that serialized objects are not guaranteed to be compatible between Guava versions. Alternatively, one would need to prevent Maven's Guava classes from being used so that both sides would always use the same Guava version.

          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: