Re: [powermock] PowerMock not working with JAXB

1,893 views
Skip to first unread message

Johan Haleby

unread,
Jun 11, 2012, 2:28:08 AM6/11/12
to powe...@googlegroups.com
Hi, 

Hmm what rule implementation are you using? If you're using a the classloader approach try switching to the Javagent

Regards,
/Johan

On Sun, Jun 10, 2012 at 3:29 PM, Markus Karg <mar...@headcrashing.eu> wrote:
It seems PowerMock ist not working with JAXB, or I am doing something completely wrong! When running this example code, the below exception is thrown by JAXB. Can anybody tell a PowerMock novice like me what my fault is? (Dependencies found at the end of this posting)
 
@PrepareForTest(X.class) public final class PowermockTest {
  @XmlRootElement public static final class X {
    private X() {  }
  }

  @Rule public PowerMockRule USE_POWER_MOCK = new PowerMockRule();
  @Test public final void x() {
    final X x = PowerMock.createMock(X.class);
    JAXB.marshal(x, System.out);
  }
}
 
javax.xml.bind.DataBindingException: javax.xml.bind.JAXBException
 - with linked exception:
[com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.sf.cglib.proxy.Callback is an interface, and JAXB can't handle interfaces.
 this problem is related to the following location:
  at net.sf.cglib.proxy.Callback
  at public net.sf.cglib.proxy.Callback[] foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84.getCallbacks()
  at foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84
net.sf.cglib.proxy.Callback does not have a no-arg default constructor.
 this problem is related to the following location:
  at net.sf.cglib.proxy.Callback
  at public net.sf.cglib.proxy.Callback[] foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84.getCallbacks()
  at foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84
]
 at javax.xml.bind.JAXB._marshal(Unknown Source)
 at javax.xml.bind.JAXB.marshal(Unknown Source)
 at foo.bar.PowermockTest.x(PowermockTest.java:28)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
 at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:52)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:2014)
 at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:885)
 at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:713)
 at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
 at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:98)
 at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78)
 at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)
 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.xml.bind.JAXBException
 - with linked exception:
[com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.sf.cglib.proxy.Callback is an interface, and JAXB can't handle interfaces.
 this problem is related to the following location:
  at net.sf.cglib.proxy.Callback
  at public net.sf.cglib.proxy.Callback[] foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84.getCallbacks()
  at foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84
net.sf.cglib.proxy.Callback does not have a no-arg default constructor.
 this problem is related to the following location:
  at net.sf.cglib.proxy.Callback
  at public net.sf.cglib.proxy.Callback[] foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84.getCallbacks()
  at foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84
]
 at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
 at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
 at javax.xml.bind.ContextFinder.find(Unknown Source)
 at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
 at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
 at javax.xml.bind.JAXB$Cache.<init>(Unknown Source)
 at javax.xml.bind.JAXB.getContext(Unknown Source)
 ... 38 more
Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.sf.cglib.proxy.Callback is an interface, and JAXB can't handle interfaces.
 this problem is related to the following location:
  at net.sf.cglib.proxy.Callback
  at public net.sf.cglib.proxy.Callback[] foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84.getCallbacks()
  at foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84
net.sf.cglib.proxy.Callback does not have a no-arg default constructor.
 this problem is related to the following location:
  at net.sf.cglib.proxy.Callback
  at public net.sf.cglib.proxy.Callback[] foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84.getCallbacks()
  at foo.bar.PowermockTest$X$$EnhancerByCGLIB$$f0189e84
 at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source)
 at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
 at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
 at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
 at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
 at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 ... 45 more
 
 
Here is the POM snippet so you see what versions are used:

<dependency> 
  <groupId>junit</groupId>
  <artifactId>junit</artifactId> 
  <version>4.10</version> 
  <scope>test</scope> 
</dependency>
<dependency> 
  <groupId>org.hamcrest</groupId> 
  <artifactId>hamcrest-core</artifactId> 
  <version>1.2.1</version> 
  <scope>test</scope> 
</dependency> 
<dependency> 
  <groupId>org.xmlmatchers</groupId> 
  <artifactId>xml-matchers</artifactId> 
  <version>0.10</version> 
  <scope>test</scope> 
</dependency> 
<dependency> 
  <groupId>org.easymock</groupId> 
  <artifactId>easymock</artifactId> 
  <version>3.1</version> 
  <scope>test</scope> 
</dependency> 
<dependency> 
  <groupId>org.powermock</groupId> 
  <artifactId>powermock-module-junit4-rule</artifactId> 
  <version>1.4.12</version> 
  <scope>test</scope> 
</dependency> 
<dependency> 
  <groupId>org.powermock</groupId> 
  <artifactId>powermock-api-easymock</artifactId> 
  <version>1.4.12</version> 
  <scope>test</scope> 
</dependency> 
<dependency> 
  <groupId>org.powermock</groupId> 
  <artifactId>powermock-classloading-xstream</artifactId> 
  <version>1.4.12</version> 
  <scope>test</scope> 
</dependency>
 
Thanks in advance!
Markus

--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To view this discussion on the web visit https://groups.google.com/d/msg/powermock/-/zS9iHL-Tn8QJ.
To post to this group, send email to powe...@googlegroups.com.
To unsubscribe from this group, send email to powermock+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/powermock?hl=en.

Markus Karg

unread,
Jun 13, 2012, 4:37:11 PM6/13/12
to powe...@googlegroups.com
As you suggested I switched to the agent approach, but this will not load itself...:

java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Provider sun.tools.attach.WindowsAttachProvider could not be instantiated: java.lang.UnsatisfiedLinkError: no attach in java.library.path

java.lang.IllegalStateException: Unable to load Java agent; please add lib/tools.jar from your JDK to the classpath

at org.powermock.modules.agent.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:97)
 
I think the problem with the agent is that I have solely JDK7 on my machine, while the stacktrace says PowerMock tries to load something developed for JDK6?

Johan Haleby

unread,
Jun 14, 2012, 12:52:04 AM6/14/12
to powe...@googlegroups.com
Hmm you may be right. You could try eager loading the agent instead.

/Johan

--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To view this discussion on the web visit https://groups.google.com/d/msg/powermock/-/Vvf-t3a273EJ.

Markus Karg

unread,
Jun 14, 2012, 2:03:43 PM6/14/12
to powe...@googlegroups.com
Eager loading solved the Java 7 issues, but brought me back to my original problem (I'm starting to drive nuts)...:
 
javax.xml.bind.DataBindingException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475 does not have a no-arg default constructor.

this problem is related to the following location:
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475

net.sf.cglib.proxy.Callback is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at net.sf.cglib.proxy.Callback
at public net.sf.cglib.proxy.Callback[] net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475.getCallbacks()
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475

net.sf.cglib.proxy.Callback does not have a no-arg default constructor.
this problem is related to the following location:
at net.sf.cglib.proxy.Callback
at public net.sf.cglib.proxy.Callback[] net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475.getCallbacks()
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475

at javax.xml.bind.JAXB._marshal(Unknown Source)
at javax.xml.bind.JAXB.marshal(Unknown Source)
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest.x(PowermockTest.java:33)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access0(ParentRunner.java:50)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475 does not have a no-arg default constructor.

this problem is related to the following location:
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475

net.sf.cglib.proxy.Callback is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at net.sf.cglib.proxy.Callback
at public net.sf.cglib.proxy.Callback[] net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475.getCallbacks()
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475

net.sf.cglib.proxy.Callback does not have a no-arg default constructor.
this problem is related to the following location:
at net.sf.cglib.proxy.Callback
at public net.sf.cglib.proxy.Callback[] net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475.getCallbacks()
at net.java.dev.webdav.jaxrs.xml.properties.PowermockTest$X$EnhancerByCGLIB$95116475

at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
at javax.xml.bind.ContextFinder.find(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXB$Cache.<init>(Unknown Source)
at javax.xml.bind.JAXB.getContext(Unknown Source)
... 27 more

Johan Haleby

unread,
Jun 18, 2012, 2:17:06 AM6/18/12
to powe...@googlegroups.com
Sorry to hear that but perhaps there's something else that's wrong. A quick search on google got me here for example: http://jersey.576304.n2.nabble.com/Error-marshalling-out-JAXB-object-of-type-quot-class-gov-hhs-acf-util-ws-grants-model-GrantsDTO-quot-td4683828.html. Are you trying to mock the DTO objects?

Regards,
/Johan

--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To view this discussion on the web visit https://groups.google.com/d/msg/powermock/-/ePogiSbm4-oJ.

Markus KARG

unread,
Jun 19, 2012, 4:25:27 PM6/19/12
to powe...@googlegroups.com

Indeed I mock the DTOs, but the problem in the link you provided is different -- that guy actually did not mock anything but simply forgot add a constructor. I do have a constructor, but the mock provided by Powermock does not. THAT is my problem. See, my original DTO works well with JAXB. Just the mock does not.

Johan Haleby

unread,
Jun 20, 2012, 1:43:16 AM6/20/12
to powe...@googlegroups.com
Alright I see. Do you really need to mock the class? Perhaps it would be alright to just stub the method to always return the same value using the stubbing API:

stub(method(PowerMockTest.class, "myMethodName")).toReturn(..);

If I remember it correctly this approach will not create a CgLib proxy but rather modify the byte-code of "PowerMockTest" directly.

Regards,
/Johan

Markus KARG

unread,
Jun 20, 2012, 5:03:26 PM6/20/12
to powe...@googlegroups.com

Yes, I need to mock the class, as the purpose is to provide an instance of the mock to the class under test as a parameter. If I cannot mock the class, I have to create an instance, which is a problem as ist constructor want more (non-mockable) DTOs then and so on. The target is to cut dependencies between classes, which is no possible by simply stubbing methods.

Johan Haleby

unread,
Jun 21, 2012, 1:53:02 AM6/21/12
to powe...@googlegroups.com
Hmm if the problem is the constructor you could suppress the constructor: 

suppress(constructor(X.class));

Regards,
/Johan

Markus KARG

unread,
Jun 21, 2012, 2:02:27 PM6/21/12
to powe...@googlegroups.com

I am not familiar to "suppres". But how does this help me? I need an instance of X.class, how to get it if the constructor is suppressed?

Markus KARG

unread,
Jun 21, 2012, 2:18:20 PM6/21/12
to powe...@googlegroups.com

Yes! Got it! IT WORKS! IT WORKS! HAPPY! :-)

 

suppress(constructor(X.class));

final X x = Whitebox.newInstance(X.class);

JAXB.marshal(new Y(x), System.out);

 

Thank you so much for your tip. This indeed is a great solution! I love PowerMock!

 

Regards

Markus

 

From: Markus KARG [mailto:mar...@headcrashing.eu]
Sent: Donnerstag, 21. Juni 2012 20:02
To: 'powe...@googlegroups.com'
Subject: RE: [powermock] PowerMock not working with JAXB

 

I am not familiar to "suppres". But how does this help me? I need an instance of X.class, how to get it if the constructor is suppressed?

 


Sent: Donnerstag, 21. Juni 2012 07:53

Johan Haleby

unread,
Jun 21, 2012, 5:30:19 PM6/21/12
to powe...@googlegroups.com
Glad you got it working and thanks for your patience.

Actually in the example you give "suppress(constructor(X.class));" is not needed. Whitebox.newInstance(..) creates a new instance of a class without invoking any constructor at all and it doesn't even require byte-code manipulation (so no need for @PrepareForTest). 

Regards,
/Johan

Markus KARG

unread,
Jun 22, 2012, 4:26:49 PM6/22/12
to powe...@googlegroups.com

I see. But in what scenario is suppression of the constructor needed then?

Johan Haleby

unread,
Jun 23, 2012, 1:46:35 PM6/23/12
to powe...@googlegroups.com
For example if you want to suppress the constructor for all new instances of the class, not just one. 

/Johan
Reply all
Reply to author
Forward
0 new messages