Skip to content

Commit

Permalink
[JENKINS-65873] [JENKINS-68954] Optimize AnonymousClassWarnings (#559)
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick authored Jul 29, 2022
1 parent cd99d11 commit b940aae
Showing 1 changed file with 8 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@

import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.remoting.AtmostOneThreadExecutor;
import hudson.remoting.Channel;

import hudson.remoting.DaemonThreadFactory;
import hudson.remoting.NamingThreadFactory;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.CodeSource;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.logging.Logger;

Expand All @@ -51,16 +47,14 @@ public class AnonymousClassWarnings {
private static final Logger LOGGER = Logger.getLogger(AnonymousClassWarnings.class.getName());
private static final Map<Class<?>, Boolean> checked = new WeakHashMap<>();

private final static ExecutorService THREAD_POOL = new AtmostOneThreadExecutor(new NamingThreadFactory(new DaemonThreadFactory(), AnonymousClassWarnings.class.getSimpleName()));

/**
* Checks a class which is being either serialized or deserialized.
* A warning will only be printed once per class per JVM session.
*/
public static void check(@NonNull Class<?> clazz) {
synchronized (checked) {
if (checked.containsKey(clazz)) {
return; // fast path
if (checked.put(clazz, true) != null) {
return;
}
}
Channel channel = Channel.current();
Expand All @@ -69,7 +63,7 @@ public static void check(@NonNull Class<?> clazz) {
} else {
// May not call methods like Class#isAnonymousClass synchronously, since these can in turn trigger remote class loading.
try {
THREAD_POOL.submit(() -> doCheck(clazz));
channel.executor.submit(() -> doCheck(clazz));
} catch (RejectedExecutionException x) {
// never mind, we tried
}
Expand All @@ -91,18 +85,11 @@ private static void doCheck(@NonNull Class<?> c) {
private static void warn(@NonNull Class<?> c, String kind) {
String name = c.getName();
String codeSource = codeSource(c);
// Need to be very defensive about calling anything while holding this lock, lest we trigger class loading-related deadlocks.
boolean doWarn;
synchronized (checked) {
doWarn = checked.put(c, true) == null;
}
if (doWarn) {
if (codeSource == null) {
LOGGER.warning("Attempt to (de-)serialize " + kind + " class " + name + "; see: https://jenkins.io/redirect/serialization-of-anonymous-classes/");
} else {
// most easily tracked back to source using javap -classpath <location> -l '<name>'
LOGGER.warning("Attempt to (de-)serialize " + kind + " class " + name + " in " + codeSource + "; see: https://jenkins.io/redirect/serialization-of-anonymous-classes/");
}
if (codeSource == null) {
LOGGER.warning("Attempt to (de-)serialize " + kind + " class " + name + "; see: https://jenkins.io/redirect/serialization-of-anonymous-classes/");
} else {
// most easily tracked back to source using javap -classpath <location> -l '<name>'
LOGGER.warning("Attempt to (de-)serialize " + kind + " class " + name + " in " + codeSource + "; see: https://jenkins.io/redirect/serialization-of-anonymous-classes/");
}
}

Expand Down

0 comments on commit b940aae

Please sign in to comment.