Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filtering by category can lead to ExceptionInInitializerError #359

Closed
nkeywal opened this issue Nov 8, 2011 · 3 comments
Closed

filtering by category can lead to ExceptionInInitializerError #359

nkeywal opened this issue Nov 8, 2011 · 3 comments

Comments

@nkeywal
Copy link
Contributor

nkeywal commented Nov 8, 2011

I am testing the support of categories in maven/surefire.

In categories.Categories#shouldRun you end up calling Description#getTestClass to check the annotations.

This is implemented by a direct classForName(className). This leads to a full initialization of this class (static & so on), even if at the end this test class won't be retained. As the initialization can be expensive for some categories of tests, it's already an issue.

In a context where there is a separation between the jvm used to select/launch the tests and the jvm used to execute them, it just does not work.

This can be very easily fixed in JUnit by not initializing the class in Description#getTestClass by calling
Class.forName(name, false, getClass().getClassLoader());

instead of

Class.forName(name);

This method exists since java 1.2 (see http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#forName%28java.lang.String,%20boolean,%20java.lang.ClassLoader%29)

Tested, it works with maven/surefire.

@Tibor17
Copy link
Contributor

Tibor17 commented Nov 8, 2011

I don't understand what ExceptionInInitializerError has to do with the JUnit in this case.
This exc is thrown because of fault in your code of static context.
Catch the cause of the exception and see what has really happened.

This would be safer:
Class.forName(name, false, Thread.currentThread().getContextClassLoader());

@nkeywal
Copy link
Contributor Author

nkeywal commented Nov 8, 2011

Thank for you answer.

Yeah, the initialization fails in our code. Some tests must be executed in an isolated JVM, and cannot be initialized in the same JVM. This works quite well with maven surefire, there is a specific parameter for this (forkMode=always).

But with categories, the selection in JUnit iterates on all the classes and initializes them to look for the meta-data (annotation & methods & so on). As it's not an isolated context if fails.

But JUnit does not need to fully initialize the class just to see if it has to be included. Not doing it prevents initialization conflict between class test categories and improve the performances as the initialization is not necessary if the test is not selected at the end. This is important when working with categories; you don't want to initialize the complex tests when you just want a quick run of the small tests category.

Yes, agreed on the class loader, the second method is better.

nkeywal added a commit to nkeywal/junit that referenced this issue Nov 11, 2011
dsaff added a commit that referenced this issue Mar 5, 2012
@marcphilipp
Copy link
Member

Fixed by #362.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants