Skip to content

Commit

Permalink
[JENKINS-11458] Channel.current() is only available from the thread t…
Browse files Browse the repository at this point in the history
…hat's executing the remote call, and that's why we saw this original error, when Maven uses a thread pool to call into this method from another worker thread.

Originally-Committed-As: dc716da16bb400f741c1e650d0f3465bb70b4d18
  • Loading branch information
kohsuke committed Oct 27, 2011
1 parent 1c1415b commit d541a16
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
38 changes: 23 additions & 15 deletions src/main/java/hudson/maven/AbstractMavenBuilder.java
Expand Up @@ -23,6 +23,9 @@
*/
package hudson.maven;

import hudson.matrix.JDKAxis;
import hudson.matrix.LabelAxis;
import hudson.matrix.TextAxis;
import hudson.model.BuildListener;
import hudson.model.Executor;
import hudson.model.Result;
Expand Down Expand Up @@ -163,13 +166,21 @@ protected Result waitForAsynchronousExecutions() {
protected class FilterImpl extends MavenBuildProxy2.Filter<MavenBuildProxy2> implements Serializable {

private MavenBuildInformation mavenBuildInformation;
private Channel channel;

/**
* Maven can internally use multiple threads to call {@link #executeAsync(BuildCallable)},
* making it impossible to rely on {@code Channel#current()} at the point of call, so
* instead we capture it when we get deserialized into Maven JVM.
* In other cases, we create FilterImpl inside Maven JVM, so we take it as a constructor.
* See JENKINS-11458
*/
private transient Channel channel;

public FilterImpl(MavenBuildProxy2 core, MavenBuildInformation mavenBuildInformation) {
super(core);
this.mavenBuildInformation = mavenBuildInformation;
}

public FilterImpl(MavenBuildProxy2 core, MavenBuildInformation mavenBuildInformation, Channel channel) {
super(core);
this.mavenBuildInformation = mavenBuildInformation;
Expand All @@ -181,24 +192,21 @@ public FilterImpl(MavenBuildProxy2 core, MavenBuildInformation mavenBuildInforma

@Override
public void executeAsync(final BuildCallable<?,?> program) throws IOException {

Channel ch = this.channel != null ? this.channel : Channel.current();

if (ch == null) {
throw new NullPointerException("current channel not available!");
}

recordAsynchronousExecution(
ch.callAsync(
channel.callAsync(
new AsyncInvoker(core,program)));
}

private static final long serialVersionUID = 1L;

public MavenBuildInformation getMavenBuildInformation()
{
public MavenBuildInformation getMavenBuildInformation() {
return mavenBuildInformation;
}
}

public Object readResolve() {
channel = Channel.current();
return this;
}

private static final long serialVersionUID = 1L;
}

}
4 changes: 2 additions & 2 deletions src/main/java/hudson/maven/Maven3Builder.java
Expand Up @@ -89,7 +89,7 @@ protected Maven3Builder(BuildListener listener,Map<ModuleName,ProxyImpl2> proxie
sourceProxies = new HashMap<ModuleName, ProxyImpl2>(proxies);
this.proxies = new HashMap<ModuleName, MavenBuildProxy2>(proxies);
for (Entry<ModuleName,MavenBuildProxy2> e : this.proxies.entrySet())
e.setValue(new FilterImpl(e.getValue(), this.mavenBuildInformation, Channel.current()));
e.setValue(new FilterImpl(e.getValue(), this.mavenBuildInformation));

this.reporters.putAll( reporters );
}
Expand Down Expand Up @@ -210,7 +210,7 @@ public MavenExecutionListener(Maven3Builder maven3Builder) {
this.proxies = new ConcurrentHashMap<ModuleName, MavenBuildProxy2>(maven3Builder.proxies);
for (Entry<ModuleName,MavenBuildProxy2> e : this.proxies.entrySet())
{
e.setValue(maven3Builder.new FilterImpl(e.getValue(), maven3Builder.mavenBuildInformation));
e.setValue(maven3Builder.new FilterImpl(e.getValue(), maven3Builder.mavenBuildInformation, Channel.current()));
executedMojosPerModule.put( e.getKey(), new CopyOnWriteArrayList<ExecutedMojo>() );
}
this.reporters.putAll( new ConcurrentHashMap<ModuleName, List<MavenReporter>>(maven3Builder.reporters) );
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/hudson/maven/MavenBuild.java
Expand Up @@ -322,13 +322,7 @@ public void executeAsync(final BuildCallable<?,?> program) throws IOException {
recordAsynchronousExecution(Channel.current().callAsync(new AsyncInvoker(core,program)));
}

public MavenBuildInformation getMavenBuildInformation()
{
return super.core.getMavenBuildInformation();
}

private static final long serialVersionUID = 1L;

}

@Override
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/hudson/maven/MavenBuildProxy.java
Expand Up @@ -240,6 +240,10 @@ public void setExecutedMojos(List<ExecutedMojo> executedMojos) {
core.setExecutedMojos(executedMojos);
}

public MavenBuildInformation getMavenBuildInformation() {
return core.getMavenBuildInformation();
}

private static final long serialVersionUID = 1L;

/**
Expand Down

0 comments on commit d541a16

Please sign in to comment.