'MyClass.class.getPackage()' returns null under javassist
jeffgrigg2 Jul 14, 2003 10:39 AMClasses have 'null' package during initialization when created under javassist, but not when preloaded by host program before loading under javassist loader.
Test program:
_ _ _
package javassistNullPackageProblem;
import java.lang.reflect.Method;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.Loader;
import javassist.NotFoundException;
import javassist.Translator;
public class JavaApplicationEntryPoint
{
public static void main(final String[] args) throws Exception
{
System.out.println("\n" + "Start of test:");
final HostClassUnderTest test = new HostClassUnderTest();
test.doNothingMethod();
//try {
call_creatANewObject_though_javassist();
//} catch (final ExceptionInInitializerError ex) {
// System.out.println(" direct call without javassist >>>---> ExceptionInInitializerError (probably a NullPointerException)");
//}
test.creatANewObject("direct call without javassist");
call_creatANewObject_though_javassist();
System.out.println("End of test.");
}
private static void call_creatANewObject_though_javassist() throws Exception
{
// This translator simply displays the names of classes that are being loaded.
final Translator translator = new Translator()
{
public void start(ClassPool pool)
{
}
public void onWrite(ClassPool pool, String className) throws NotFoundException, CannotCompileException
{
final CtClass clazz = pool.get(className);
System.out.println(" Loading class: " + className);
}
};
// Setup javassist.
final ClassPool jaClassPool = ClassPool.getDefault(translator);
final Loader jaLoader = new Loader(jaClassPool);
Thread.currentThread().setContextClassLoader(jaLoader);
// Load the following class under javassist.
final Class clazz = jaLoader.loadClass("javassistNullPackageProblem.HostClassUnderTest");
// Create an instrumented instance of this class.
final Object instrumentedTestInstance = clazz.newInstance();
// Find the 'public void creatANewObject(final String message)' method.
final Class[] parameterClasses = new Class[] { String.class };
final Method currentMethod = clazz.getDeclaredMethod("creatANewObject", parameterClasses);
// Call 'instrumentedTestInstance.creatANewObject("call method through javassist");'
try
{
final Object[] parameterValues = new Object[] { "call method through javassist" };
currentMethod.invoke(instrumentedTestInstance, parameterValues);
}
catch (final java.lang.reflect.InvocationTargetException exceptionWrapper)
{
/*NOTREACHED*/
final Throwable originalException = exceptionWrapper.getTargetException();
if (originalException != null) {
if (originalException instanceof Exception) {
throw (Exception) originalException;
} else if (originalException instanceof Error) {
throw (Error) originalException;
}
}
throw exceptionWrapper;
}
}
}
_ _ _
package javassistNullPackageProblem;
import javassistNullPackageProblem.someOtherPackage.ChildClassWithPackageProblem;
public class HostClassUnderTest
{
public void doNothingMethod()
{
}
public void creatANewObject(final String message)
{
final Object anonymousInnerClassInstance = new Object()
{
final Class clazz = ChildClassWithPackageProblem.class;
final Package staticInstanceVariableFromClass = ChildClassWithPackageProblem.currentPackage;
final Package reflectionGetPackageCall = clazz.getPackage();
final Package reflectionCallFromClassReference = ChildClassWithPackageProblem.class.getPackage();
{
if (staticInstanceVariableFromClass == null && reflectionGetPackageCall == null && reflectionCallFromClassReference == null)
{
System.out.println(" " + message + " >>>---> 'package' is 'null'");
}
else if (staticInstanceVariableFromClass != null || reflectionGetPackageCall != null || reflectionCallFromClassReference != null)
{
System.out.println(" " + message + " >>>---> 'package' is defined");
}
else
{
/*NOTREACHED*/
System.out.println(" " + message + " >>>---> some mix of 'null' and other in package");
}
}
};
int i=0; // (Place holder for debugger break point.)
}
}
_ _ _
package javassistNullPackageProblem.someOtherPackage;
public class ChildClassWithPackageProblem
{
public static final Package currentPackage = ChildClassWithPackageProblem.class.getPackage();
// Uncomment the following line to receive a java.lang.NullPointerException
// (...within a java.lang.ExceptionInInitializerError, which is within a java.lang.reflect.InvocationTargetException)
//private static final String packageName = currentPackage.getName();
}
_ _ _
Results:
Start of test:
Loading class: javassistNullPackageProblem.HostClassUnderTest
Loading class: javassistNullPackageProblem.HostClassUnderTest$1
Loading class: javassistNullPackageProblem.someOtherPackage.ChildClassWithPackageProblem
call method through javassist >>>---> 'package' is 'null'
direct call without javassist >>>---> 'package' is defined
call method through javassist >>>---> 'package' is defined
End of test.
_ _ _
The interesting thing to note is where it says "'package' is 'null'" -- which means that the class 'javassistNullPackageProblem.someOtherPackage.ChildClassWithPackageProblem' has 'null' for its 'java.lang.Package'.
Note also, two lines later, where it says "'package' is defined" -- meaning that the same class, created the same way, now has a proper package.
_ _ _
This is a simple test program which reproduces the problem, but I'm not sure how to debug it from here.
Thank you for any assistance you may be able to offer!
- jeff