Skip to content

Commit

Permalink
Run CommandMap with context class loader (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
basil authored Jan 8, 2022
1 parent 9b6f72b commit 7f6eab6
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.jenkins.plugins.javax.activation;

import hudson.init.InitMilestone;
import hudson.init.Initializer;
import javax.activation.CommandMap;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

@Restricted(NoExternalUse.class)
public class CommandMapInitializer {

@Initializer(after = InitMilestone.PLUGINS_PREPARED, before = InitMilestone.PLUGINS_STARTED)
public static synchronized void init() {
Thread t = Thread.currentThread();
ClassLoader orig = t.getContextClassLoader();
t.setContextClassLoader(CommandMapInitializer.class.getClassLoader());
try {
// Getting the default command map fetches a per-thread-context-class-loader default.
// Setting the default command map removes the per-thread-context-class-loader command map.
CommandMap.setDefaultCommandMap(new DelegatingCommandMap(CommandMap.getDefaultCommandMap()));
} finally {
t.setContextClassLoader(orig);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.jenkins.plugins.javax.activation;

import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Objects;
import java.util.function.Supplier;
import javax.activation.CommandInfo;
import javax.activation.CommandMap;
import javax.activation.DataContentHandler;
import javax.activation.DataSource;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

@Restricted(NoExternalUse.class)
public class DelegatingCommandMap extends CommandMap {
private final CommandMap delegate;

public DelegatingCommandMap(@NonNull CommandMap delegate) {
this.delegate = Objects.requireNonNull(delegate);
}

private static final <T> T runWithContextClassLoader(Supplier<T> supplier) {
Thread t = Thread.currentThread();
ClassLoader orig = t.getContextClassLoader();
t.setContextClassLoader(DelegatingCommandMap.class.getClassLoader());
try {
return supplier.get();
} finally {
t.setContextClassLoader(orig);
}
}

@Override
public CommandInfo[] getPreferredCommands(String mimeType) {
return runWithContextClassLoader(() -> delegate.getPreferredCommands(mimeType));
}

@Override
public CommandInfo[] getPreferredCommands(String mimeType, DataSource ds) {
return runWithContextClassLoader(() -> delegate.getPreferredCommands(mimeType, ds));
}

@Override
public CommandInfo[] getAllCommands(String mimeType) {
return runWithContextClassLoader(() -> delegate.getAllCommands(mimeType));
}

@Override
public CommandInfo[] getAllCommands(String mimeType, DataSource ds) {
return runWithContextClassLoader(() -> delegate.getAllCommands(mimeType, ds));
}

@Override
public CommandInfo getCommand(String mimeType, String cmdName) {
return runWithContextClassLoader(() -> delegate.getCommand(mimeType, cmdName));
}

@Override
public CommandInfo getCommand(String mimeType, String cmdName, DataSource ds) {
return runWithContextClassLoader(() -> delegate.getCommand(mimeType, cmdName, ds));
}

@Override
public DataContentHandler createDataContentHandler(String mimeType) {
return runWithContextClassLoader(() -> delegate.createDataContentHandler(mimeType));
}

@Override
public DataContentHandler createDataContentHandler(String mimeType, DataSource ds) {
return runWithContextClassLoader(() -> delegate.createDataContentHandler(mimeType, ds));
}

@Override
public String[] getMimeTypes() {
return runWithContextClassLoader(() -> delegate.getMimeTypes());
}
}

0 comments on commit 7f6eab6

Please sign in to comment.