Open t-8ch opened 6 years ago
Could you change JAVA environment to Java9 or Java10? It should be caused <Java8 defineClass
issue.
Such as add below snippet in pom.
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>10</source>
<target>10</target>
</configuration>
</plugin>
</plugins>
</build>
Indeed this works. Unfortunately I am limited to Java8 in this project for the time being. Feel free to close the issue if it is out of scope.
Maybe my suggestion was not so precise.
No need to change source/target to 10. Only need to make sure JRE is Java9/10.
Well, I am limited to JRE 8. The project is a plugin for a third-party software which does not work with anything else.
Aha, there is some tricky workaround. You could create one instance before you use javassist to manipulate it. Like:
new ClassWithStaticInitializer();
...
String name = "x.x.x.ClassWithStaticInitializer";
ClassPool cp = new ClassPool(true);
CtClass ctClass = cp.get(name);
Class<?> c = ctClass.toClass();
Gives me
javassist.CannotCompileException: by java.lang.ClassFormatError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "x/x/x/ClassWithStaticInitializer"
at javassist.util.proxy.DefineClassHelper.toClass(DefineClassHelper.java:250)
at javassist.ClassPool.toClass(ClassPool.java:1120)
at javassist.ClassPool.toClass(ClassPool.java:1083)
at javassist.ClassPool.toClass(ClassPool.java:1041)
at javassist.CtClass.toClass(CtClass.java:1278)
at a.b.PatchingTest.testClassInitialization(PatchingTest.java:37)
(I had to use the code from master because of #209)
Aha, I made a mistake by typo.
I created one empty class ClassWithStaticInitializer1
under x.x.x
It should be new ClassWithStaticInitializer1();
BTW, has fix of #209 resolved your issue? Seems it only expose the real exception.
That works indeed. Thanks! (This also explains why it works for classes in the same package as the modifying class)
Depends on what you mean by "your issue".
When running into the duplicate class declaration without the fix from master I only got a nondescript NPE while creating the CannotCompileException
. With the fix I got the useful error I posted here.
Is this issue something that can/should be fixed in Javassist?
Currently, it will report CannotCompileException
if you have something like class.getPackage()
in your code. Not sure if you have workaround.
And this issue will be gone after switching to Java9/10. I think @chibash is the one can decide if it should be fixed for <Java8 in Javassist.
I'll fix it if there is a good way to solve the problem in Java 8. This seems a sort of bug of Class#getPackage() in Java 8.
When creating a new class (by modifying an existing one) the newly created class looses its package information. This only happens when the class using javassist is in a different package than the modified class.
When the class runs a static initializer using the package information this will result in an
ExceptionInInitializerError
Reproduction case (tested with 3.23.1-GA and current git master (a3d1aa25133c2ec473e9b3ebe2bfa5b4ebe5759e): https://github.com/t-8ch/javassist-issue-lost-package-information
(Feel free to change the subject of the issue, I am not sure how to summarize it nicely)