问题
I have some test classes that need to verify that GLFW-functions were called. But when I want to execute all tests in IntelliJ then I get the error:
Native Library lwjgl.dll already loaded in another classloader
I use Powermock to verify that the static methods have been called:
@RunWith(PowerMockRunner.class)
@PrepareForTest({GLFW.class})
public class GlfwWindowImplTest {
// ...
@Test
public void update_swapsBufferAndPollsEvents() {
GlfwWindowImpl target = new GlfwWindowImpl(1L);
mockStatic(GLFW.class);
target.update();
verifyStatic();
GLFW.glfwSwapBuffers(1L);
verifyStatic();
GLFW.glfwPollEvents();
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({GLFW.class})
public class GlfwWindowSystemImplTest {
// ...
@Test(expected = GlfwInitializeException.class)
public void initialize_throwsExceptionIfGlfwInitFails() {
GlfwWindowSystemImpl target = new GlfwWindowSystemImpl();
mockStatic(GLFW.class);
when(GLFW.glfwInit()).thenReturn(GL_FALSE);
target.initialize();
}
}
回答1:
It may be a bit late to answer this post, but I ran into a similar problem and I was able to solve it with PowerMock. PowerMock has @SuppressStaticInitializationFor that should help you overcome this issue. Section Suppress static initializer in the link below has a nice example about how to do that:
https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior
Basically, in your case, there could be a class that is calling System.loadLibrary("lwjgl"). You need to locate that class. Example:
public class SomeClass {
...
static {
System.loadLibrary ("lwjgl");
}
...
}
Then in your test class use @SuppressStaticInitializationFor with the fully qualified name of the class:
@SuppressStaticInitializationFor("com.example.SomeClass")
If in case the class doing the loadLibrary call is an inner class, then you need to add $InnerClass to fully qualify the inner class. Example:
public class SomeClass {
...
public static class SomeInnerClass {
static {
System.loadLibrary ("lwjgl");
}
}
...
}
Then you need to use:
@SuppressStaticInitializationFor("com.example.SomeClass$SomeInnerClass")
回答2:
@PrepareForTest({GLFW.class})
loads the ClassLoader for the native library lwjgl.dll
which is already loaded in the ClassLoader.
You can use the @PowerMockIgnore
to defer the loading of classes with the names supplied to value() to the system ClassLoader.
For example suppose you'd like to defer the loading of all classes in the org.myproject package and all its sub-packages but you still like to prepare "MyClass" for test. Then you do like this:
@PowerMockIgnore("org.myproject.*")
@PrepareForTest(MyClass.class)
@RunWith(PowerMockRunner.class)
public class MyTest {
...
}
JavaDoc Reference
回答3:
@PrepareForTest({GLFW.class})
create new ClassLoader
and load ammended class in it. I suspect that GLFW
load lwjgl
library in its static initializer section.
You can try to unload library, but I don't know what consequences it may lead to.
I suggest wrap GLFW
and use that wrapper in your applicatin.
来源:https://stackoverflow.com/questions/39248363/junit-powermock-native-library-already-loaded-in-another-classloader