Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

Recently at work a big amount of effort has been put in to adding unit tests for as much code as possible. Due to the nature of the services that we work with, we required to make heavy use of PowerMock. It's a great framework that lets us mock out certain classes that are usually hard to mock, like statics, and unfortunately at one point I started to see LinkageError exceptions being thrown that looked like this...
 Exception
WARNING: Error while registering Oracle JDBC Diagnosability MBean.
java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:262)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:206)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at oracle.jdbc.driver.OracleDriver.registerMBeans(OracleDriver.java:360)
at oracle.jdbc.driver.OracleDriver$1.run(OracleDriver.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:195)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at java.sql.DriverManager$2.run(DriverManager.java:603)
at java.sql.DriverManager$2.run(DriverManager.java:583)
at java.security.AccessController.doPrivileged(Native Method)
at java.sql.DriverManager.loadInitialDrivers(DriverManager.java:583)
at java.sql.DriverManager.<clinit>(DriverManager.java:101)


So what does this mean? Well PowerMock prepares and loads mocked classes using its MockClassLoader. In some cases this behaviour is undesirable and the mocked class must be loaded by the system class loader instead. This is easily done with the PowerMockIgnore annotation like this...
 Java
...
@PowerMockIgnore("javax.management.*")
public class MyTestClass {
...
}


So in my case since the LinkageError was for the javax/management/MBeanServer class, I use the "javax.management.*" value to make sure that everything in the javax.management package is deferred to the system class loader (I could have used the specific class but I chose to use the entire package).

There is a way to apply this type of configuration globally by creating a file, "org/powermock/extensions/configuration.properties", and adding it to the classpath (if using Maven in the src/test/resources directory). The configuration file is a standard Java Properties file and needs to have the "powermock.global-ignore" set the same way as the annotation, however I couldn't get this to work.



-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.