Use javaagent to determine if logger class is initialized in test
This commit is contained in:
parent
0b92413d4a
commit
f2e4b7d4b1
|
@ -21,11 +21,12 @@ class CustomLogManagerTest extends Specification {
|
|||
break
|
||||
}
|
||||
}
|
||||
final URL customAgent = IntegrationTestUtils.createJarWithClasses(LogManagerSetter.getName(), LogManagerSetter)
|
||||
|
||||
expect:
|
||||
agentArg != null
|
||||
IntegrationTestUtils.runOnSeparateJvm(LogManagerSetter.getName()
|
||||
, [agentArg, "-Ddd.jmxfetch.enabled=true"] as String[]
|
||||
, [agentArg, "-javaagent:" + customAgent.getPath(), "-Ddd.jmxfetch.enabled=true"] as String[]
|
||||
, "" as String[]
|
||||
, true) == 0
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
|
@ -77,20 +78,32 @@ public class IntegrationTestUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** See {@link IntegrationTestUtils#createJarWithClasses(String, Class[])} */
|
||||
public static URL createJarWithClasses(final Class<?>... classes) throws IOException {
|
||||
return createJarWithClasses(null, classes);
|
||||
}
|
||||
/**
|
||||
* Create a temporary jar on the filesystem with the bytes of the given classes.
|
||||
*
|
||||
* <p>The jar file will be removed when the jvm exits.
|
||||
*
|
||||
* @param mainClassname The name of the class to use for Main-Class and Premain-Class. May be null
|
||||
* @param classes classes to package into the jar.
|
||||
* @return the location of the newly created jar.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static URL createJarWithClasses(final Class<?>... classes) throws IOException {
|
||||
public static URL createJarWithClasses(final String mainClassname, final Class<?>... classes)
|
||||
throws IOException {
|
||||
final File tmpJar = File.createTempFile(UUID.randomUUID().toString() + "-", ".jar");
|
||||
tmpJar.deleteOnExit();
|
||||
|
||||
final Manifest manifest = new Manifest();
|
||||
if (mainClassname != null) {
|
||||
Attributes mainAttributes = manifest.getMainAttributes();
|
||||
mainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
mainAttributes.put(Attributes.Name.MAIN_CLASS, mainClassname);
|
||||
mainAttributes.put(new Attributes.Name("Premain-Class"), mainClassname);
|
||||
}
|
||||
final JarOutputStream target = new JarOutputStream(new FileOutputStream(tmpJar), manifest);
|
||||
for (final Class<?> clazz : classes) {
|
||||
addToJar(clazz, target);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package jvmbootstraptest;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.IllegalClassFormatException;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
public class LogManagerSetter {
|
||||
|
@ -8,22 +12,38 @@ public class LogManagerSetter {
|
|||
// loggerClassName = java.util.logging.Logger
|
||||
private static final String loggerClassName =
|
||||
"java.util.logging.TMP".replaceFirst("TMP", "Logger");
|
||||
private static final String loggerInternalName = loggerClassName.replace('.', '/');
|
||||
private static final AtomicBoolean loggerInitialized = new AtomicBoolean(false);
|
||||
|
||||
public static void premain(final String agentArgs, final Instrumentation inst) throws Exception {
|
||||
inst.addTransformer(
|
||||
new ClassFileTransformer() {
|
||||
@Override
|
||||
public byte[] transform(
|
||||
ClassLoader loader,
|
||||
String className,
|
||||
Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain,
|
||||
byte[] classfileBuffer)
|
||||
throws IllegalClassFormatException {
|
||||
if (loggerInternalName.equals(className)) {
|
||||
loggerInitialized.compareAndSet(false, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
final ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
|
||||
|
||||
// once the logger class has been initialized, we know jmxfetch is running and can proceed with
|
||||
// the test
|
||||
final Method method =
|
||||
ClassLoader.class.getDeclaredMethod("findBootstrapClassOrNull", String.class);
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
while (method.invoke(systemLoader, loggerClassName) == null) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
} finally {
|
||||
method.setAccessible(false);
|
||||
while (!loggerInitialized.get()) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
systemLoader.loadClass(loggerClassName);
|
||||
// at this point the logger is loaded and fully initialized
|
||||
|
||||
System.setProperty("java.util.logging.manager", CustomLogManager.class.getName());
|
||||
customAssert(
|
||||
|
|
Loading…
Reference in New Issue