I want to make some webservices with spray and akka.
GET resquests works fine (get elements list, a value... with spray-json) but with my Authentication request, I got an expection, and I don't know why.
I've make some unit tests to see if serialization/deserialization works fine with marshallers, and I see a well formed json object.
Here's my stacktrace :
Uncaught error from thread [on-spray-can-akka.actor.default-dispatcher-3] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[on-spray-can]
java.lang.AbstractMethodError: com.example.components.models.authentication.IdentityWithProfile$.viaSeq(Lscala/Function1;Lspray/json/JsonFormat;)Lspray/json/RootJsonFormat;
at spray.json.CollectionFormats$class.seqFormat(CollectionFormats.scala:77)
at com.example.components.models.authentication.IdentityWithProfile$.seqFormat(Identity.scala:15)
at com.example.components.models.authentication.IdentityWithProfile$.<init>(Identity.scala:16)
at com.example.components.models.authentication.IdentityWithProfile$.<clinit>(Identity.scala)
at com.example.api.marshallers.AuthenticationResult$.<init>(AuthenticationResult.scala:12)
at com.example.api.marshallers.AuthenticationResult$.<clinit>(AuthenticationResult.scala)
at com.example.api.RouteService$$anonfun$authenticate$2.apply(RouteService.scala:23)
at com.example.api.RouteService$$anonfun$authenticate$2.apply(RouteService.scala:23)
at spray.routing.directives.RouteDirectives$$anonfun$complete$1$$anon$3.apply(RouteDirectives.scala:49)
at spray.routing.directives.RouteDirectives$$anonfun$complete$1$$anon$3.apply(RouteDirectives.scala:48)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(BasicDirectives.scala:92)
at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(BasicDirectives.scala:92)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(BasicDirectives.scala:92)
at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(BasicDirectives.scala:92)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(BasicDirectives.scala:92)
at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(BasicDirectives.scala:92)
at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:30)
at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:29)
at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:30)
at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:29)
at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:30)
at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:29)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
at spray.routing.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$4.apply(ExecutionDirectives.scala:35)
at spray.routing.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$4.apply(ExecutionDirectives.scala:33)
at spray.routing.HttpServiceBase$class.runSealedRoute$1(HttpService.scala:36)
at spray.routing.HttpServiceBase$$anonfun$runRoute$1.applyOrElse(HttpService.scala:46)
at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
at com.example.api.RouteActor.aroundReceive(RouteActor.scala:5)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
at akka.dispatch.Mailbox.run(Mailbox.scala:220)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
I've found topics about this error, and the problem was scala/spray/akka versions, but I checked and I use correct versions (scala 2.10.4/spray 1.3.2/akka 2.3.6)
Anyone has a solution, or a track ?
EDIT :
GET webservices don't work too... I think it's a configuration problem.
Related
I've installed samestep/boot-refresh 0.1.0. In the boot REPL, when I change a source file and type:
boot.user=> (boot (refresh))
I get:
java.lang.IllegalStateException: Can't set!: *e from non-binding thread
What am I doing wrong?
Here's the full stack trace:
boot.user=> *e
#error {
:cause "Can't set!: *e from non-binding thread"
:via
[{:type java.lang.IllegalStateException
:message "Can't set!: *e from non-binding thread"
:at [clojure.lang.Var set "Var.java" 218]}]
:trace
[[clojure.lang.Var set "Var.java" 218]
[clojure.tools.namespace.repl$print_and_return invokeStatic "repl.clj" 22]
[clojure.tools.namespace.repl$print_and_return invoke "repl.clj" 20]
[clojure.tools.namespace.repl$do_refresh invokeStatic "repl.clj" 96]
[clojure.tools.namespace.repl$do_refresh invoke "repl.clj" 82]
[clojure.tools.namespace.repl$refresh invokeStatic "repl.clj" 145]
[clojure.tools.namespace.repl$refresh doInvoke "repl.clj" 128]
[clojure.lang.RestFn invoke "RestFn.java" 397]
[samestep.boot_refresh$eval541$fn__542$fn__547$fn__548$fn__549 invoke "boot_refresh.clj" 14]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 646]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[samestep.boot_refresh$eval541$fn__542$fn__547$fn__548 invoke "boot_refresh.clj" 13]
[boot.core$run_tasks invoke "core.clj" 1019]
[boot.core$boot$fn__918 invoke "core.clj" 1029]
[clojure.core$binding_conveyor_fn$fn__4676 invoke "core.clj" 1938]
[clojure.lang.AFn call "AFn.java" 18]
[java.util.concurrent.FutureTask run "FutureTask.java" 266]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
[java.lang.Thread run "Thread.java" 745]]}
My own code isn't mentioned in the stack trace. I have seen (boot (refresh)) work from the REPL before, but I haven't been able to find out what I'm doing differently to cause this error.
Update 1
After a long binary search with many print statements—since, as explained in #amalloy's answer, the stack trace for the real exception is inaccessible—I discovered this:
In a namespace called move-test, this statement:
(def subset-sum-spec fargish.workspace-test/subset-sum-spec)
was causing (boot (refresh)) to fail. When I replaced it with:
(:require … [fargish.workspace-test :refer [subset-sum-spec]] …)
in the ns statement, (boot (refresh)) worked again. That fixes the current problem for now, but I'd still like to know what's going on.
Update 2
Continuing to try to get (boot (refresh)) to work, it's become clear that the problem is different every time. #amalloy's answer suggests that the real answer to this question would be some way to find the exception and stack trace that c.t.n.repl/print-and-return is failing to store in *e. I've tried a few ideas, but the relevant variables seem to be private and hard to dig out.
How can you find out the error that causes (boot (refresh)) to fail?
I don't know about boot or c.t.namespace, but that error trace looks like boot is running refresh from a new thread, and refresh is running into some error. It tries to propagate the error for you by setting *e, but it can't set *e because it's not on the repl thread. So instead of seeing the real error, you're getting this useless "error caused by failing to report an error".
The error seems to be detected here, and c.t.namespace tries to avoid setting *e when there's no repl running (by checking whether *e is bound), but it incorrectly assumes that if a repl is running then the repl thread must be the one it's being called from, whereas apparently boot calls it from a different thread. Have you tried just calling (refresh)? I don't know what the (boot ...) wrapper is supposed to do, but you might not need it, and it seems to be causing trouble. This also explains why you've seen (boot (refresh)) work: the (boot ...) wrapper (probably) doesn't break things itself, but instead just causes the error reporting to get worse when something else is broken.
Of course, once you fix that issue, the result will not be that your refresh works: you'll just be able to see the actual error, instead of this meta-error! Hopefully that will be enough to help you make progress.
The repl usually has *e bound in the environment of where you execute your code. If anything that needs *e is ran in another thread or outside of the repl it will fail to have an *e to bind to.
I have by-passed this issue by using with-binding to ensure that the refresh fn will always have *eto bind the error to.
(with-bindings {#'*e nil} (refresh))
Once refresh has *e to bind the error to, it should prn the error for you.
We have a JAX-WS/JAXB binding to an external web-service that is working fine on Java 7 (1.7.0u80) with the included reference implementations. During migration to Java 8 (1.8.0u66) the web service calls generally work OK, however it cannot unmarshall SOAP faults and their detail elements to Java Exceptions with custom detail any longer, giving instead a prefix not bound to a namespace error.
The failure is
Caused by: javax.xml.ws.WebServiceException: java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:138)
at com.sun.xml.internal.ws.client.sei.StubHandler.readResponse(StubHandler.java:238)
at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:189)
at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:276)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:104)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
at com.sun.proxy.$Proxy61.proprietaryServiceCall(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.springframework.remoting.jaxws.JaxWsPortClientInterceptor.doInvoke(JaxWsPortClientInterceptor.java:580)
at org.springframework.remoting.jaxws.JaxWsPortClientInterceptor.doInvoke(JaxWsPortClientInterceptor.java:554)
... 56 more
Caused by: java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
at com.sun.xml.internal.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:355)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.selectLoader(LeafPropertyXsiLoader.java:75)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.startElement(LeafPropertyXsiLoader.java:58)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:559)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:229)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:112)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:354)
at com.sun.xml.internal.bind.v2.runtime.BridgeImpl.unmarshal(BridgeImpl.java:124)
at com.sun.xml.internal.bind.api.Bridge.unmarshal(Bridge.java:309)
at com.sun.xml.internal.ws.db.glassfish.BridgeWrapper.unmarshal(BridgeWrapper.java:217)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.getJAXBObject(SOAPFaultBuilder.java:304)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:135)
The response from the external service looks like the below (I have anonymized type names, but left everything else)
<env:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>ERROR MESSAGE</faultstring>
<detail>
<n1:ProprietaryException xmlns:n1="java:com.company.service" xsi:type="n1:ProprietaryException">
<errorCode xsi:type="xsd:int">400</errorCode>
<errorReason xsi:type="xsd:string">Specific error</errorReason>
</n1:ProprietaryException>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
The problem is with the xsd:int and xsd:string in the faultCode and faultReason. It seems like the prefix/namespace declarations are not being inherited from the top level envelope when binding. The problem looks similar to this question except unlike that question this is about SOAP Fault handling, and in my case, the code is deep inside JAX-WS and JAXB so I have no idea how we could fix it or workaround it.
Unless the old code was relying on some behaviour that never should have worked, I can't help but conclude something has been broken between JAX-WS and JAXB in their Java 8 implementations.
Update (Jan 4 2016): I've also tried this with a CXF 3.1.4 client instead of the Metro RI. Same problem. It seems to be the same issue as mentioned here
Update (Jan 6 2016): I've narrowed this problem to a change introduced to the JAXB RI 2.2.6. Thus the problem can be replicated on Java 7 with a forced upgrade to JAXB RI 2.2.6. It seems it might relate to changes made in JAXB-890.
I have tested working around this in at least two different ways:
Use Java 8 with JAXB force downgraded back to 2.2.5 (JAX-WS version doesn't seem to matter). Doesn't seem a good long-term solution.
I found that -Dcom.sun.xml.bind.improvedXsiTypeHandling=false (or the equivalent .internal property if using the bundled JDK JAXB RI) seems to workaround the issue. But I have no idea what this setting really does; or what the implications would be for the rest of the JAXB usage in my system.
Any ideas for how to proceed here?
One workaround which seems to work (but should not be required and has other consequences for JAXB usage in other parts of my application which make it undesirable) is to replace the JAXB provider with EclipseLink MOXy (tested 1.6.2).
Given this works, it does seem that this is a problem in the JAXB RI (Metro) version included with Java 8 (up to at least 1.8.0u66).
Faced a similar issue recently. Switching to MOXy or using some obscure JVM parameters wasn't an option, so I looked on ways to implement some sort of a "pre-unmarshall hack" mentioned above.
Turns out, if you make a SOAPHandler like so
public class NamespaceBindingShim implements SOAPHandler<SOAPMessageContext> {
#Override
public boolean handleMessage(SOAPMessageContext context) {
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
context.getMessage();
return true;
}
#Override
public void close(MessageContext context) {
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
and then add it to the handler chain of your client like so
ServicePort port = service.getServicePort();
BindingProvider bindingProvider = (BindingProvider) port;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(Collections.singletonList(new NamespaceBindingShim()));
then everything miraculously works and proprietary SOAP faults get converted to proprietary exceptions.
I don't yet know why this works and whether it breaks something else, since it's pretty obvious I don't do any XML manipulation inside the handler (the getter only invokes lazy DOM initialization for the envelope AFAICT).
EDIT: after more testing I have discovered this to pass in some tests, but to fail in others. Back to the drawing board...
So I set up the power mock based on the reference guide here. It all seems to run perfectly fine with a single test class. But when executing multiple JUnit tests I am getting the following error on the second test class.
As you can see from the stacktrace below I am trying to mock a otto Bus instance. It seemed to mock properly on the first test class but on the the second class I am getting this class cast exception.
On the stacktrace I am getting suggestion to disable Objenisis cache but I am not sure how to accomplish that and if that is actually the root cause as I am using classloading-xstream:1.6.2 as per the Robolectric Wiki link attached above.
The thing is my setup works well if I run a single JUnit test class, but once I try to run all the tests in a package only the first test will work and subsequent tests will get the class cast exception.
org.mockito.exceptions.base.MockitoException:
ClassCastException occurred while creating the mockito proxy :
class to mock : 'com.squareup.otto.Bus', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader#1593948d'
created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader#1593948d'
proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader#618ff5c2'
instance creation by : ObjenesisInstantiator
You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassCastException: Cannot cast com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196 to com.squareup.otto.Bus
at java.lang.Class.cast(Class.java:3369)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:59)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
at org.mockito.Mockito.mock(Mockito.java:1285)
at org.mockito.Mockito.mock(Mockito.java:1163)
... 36 more
org.mockito.exceptions.base.MockitoException:
ClassCastException occurred while creating the mockito proxy :
class to mock : 'com.squareup.otto.Bus', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader#1593948d'
created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader#1593948d'
proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader#618ff5c2'
instance creation by : ObjenesisInstantiator
You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:6
I would suggest to disable ClassCache of Mockito as suggested in the exception message
.
Here is how I disable Mockito ClassCache by adding a MockitoConfiguration class in Android Studio.
Under your unit test directory, src/test/java, create a package directory that is exactly the same as Mockito configuration package, org/mockito/configuration.
So under the full test directory src/test/java/org/mockito/configuration, add a new class named MockitoConfiguration.
Overwrite the enableClassCache() method as following.
package org.mockito.configuration;
public class MockitoConfiguration extends DefaultMockitoConfiguration {
#Override
public boolean enableClassCache() {
return false;
}
}
When you run your Unit test under src/java/test, your MockitoConfiguration should be loaded and Mockito class cache should be disabled.
Hope it helps.
So I solved this problem by adding
#PowerMockIgnore({ "*.*" })
#PrepareForTest({ StaticClass1.class,StaticClass2.class })
That will make Power mock ignore all the classes. For my case PowerMock was classloading the Bus which in my code was actually mocked by Mockito.Once I added the annotations above all the classes in the testsuite worked without any errors.
I've just started writing unit test cases JerseyTest framework. I've followed this example
http://www.hascode.com/2011/09/rest-assured-vs-jersey-test-framework-testing-your-restful-web-services/comment-page-1/#comment-4791,
I'm able to run the service to get the JSON data. But when I run the unit test using JUnit, I'm facing the following issue. Any suggestions would be greatly appreciated.
com.sun.jersey.test.framework.spi.container.TestContainerException: The default test container factory, null, could not be instantiated
at com.sun.jersey.test.framework.JerseyTest.getDefaultTestContainerFactory(JerseyTest.java:408)
at com.sun.jersey.test.framework.JerseyTest.getTestContainerFactory(JerseyTest.java:273)
at com.sun.jersey.test.framework.JerseyTest.<init>(JerseyTest.java:165)
at com.hascode.tutorial.rest.UserServiceTestUsingJerseyTestFramework.<init>(UserServiceTestUsingJerseyTestFramework.java:17)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
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: java.lang.NullPointerException
at com.sun.jersey.test.framework.JerseyTest.getDefaultTestContainerFactory(JerseyTest.java:406)
... 25 more
You probably forgot to add a module containing a Jersey test container implementation, e.g. jersey-test-framework-grizzly2:
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-grizzly2</artifactId>
<version>1.18.1</version>
<scope>test</scope>
</dependency>
You can find more info in the chapter dedicated to Jersey Test Framework.
I am currently working on an inherited codebase. One of the critical missing pieces is unit testing. I seem to have run into a roadblock while trying to set up some unit tests in NUnit.
I created a separate unit testing project as normal, added the necessary references to SubSonic, NUnit and the various DLLs created by the application and set up a dummy unit test to ensure everything is set up correctly. The problems started when I attempted to reference some of the objects generated by SubSonic. I created this test to list users:
[Test]
public void CanListUsers()
{
UserCollection users = UserController.List(UserController
.Query()
.Where(User.Columns.IsDeleted, false));
Assert.IsNotNull(users);
}
and got this exception:
Can't find the SubSonicService in your
application's config
I fixed that by pulling out the parts of the Web.config that were related to SubSonic into an App.config in the unit testing project. Now, when I rerun the unit tests, I get:
UnitTests.TestClass.CanListUsers:
System.Reflection.TargetInvocationException
: Exception has been thrown by the
target of an invocation. ---->
System.Configuration.ConfigurationErrorsException
: Could not load type
'Utility.SqlSubsonicProvider' from
assembly 'System.Web, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'.
This exception has me confused because SqlSubsonicProvider is a class in the Utility namespace and can be seen in Object Browser so why is it being looked for in System.Web?
Edit: Okay, I have rearranged the namespaces in the solution so that they make more sense. I think that fixed the above error. Unfortunately I'm now getting this error:
ChannelMechanics.UnitTests.TestClass.CanListVendors:
System.Reflection.TargetInvocationException : Exception has been thrown by the target
of an invocation.
----> System.NullReferenceException : Object reference not set to an instance of
an object.
What's even stranger is that the unit test passes when I use Visual Studio's "Attach to Process" command in the Debug menu and attach to the NUnit GUI. My theory was that the null object would be easily spotted from within the debugger.
If it helps, my App.config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="SubSonicService"
type="SubSonic.SubSonicSection, SubSonic"
requirePermission="false"/>
</configSections>
<connectionStrings>
<add name="DatabaseConnection"
connectionString="*removed*"/>
</connectionStrings>
<SubSonicService defaultProvider="TestProvider">
<providers>
<clear />
<add name="TestProvider"
type="SubSonic.SqlDataProvider, SubSonic"
connectionStringName="DatabaseConnection"
generatedNamespace="Test"/>
</providers>
</SubSonicService>
</configuration>
The exception details are:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type,
Boolean publicOnly, Boolean noCheck, Boolean& canBeCached,
RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis,
Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,
Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance[T]()
at SubSonic.ActiveController`2.Query()
at UnitTests.TestClass.CanListVendors() in UnitTests\TestClass.cs:line 59
--NullReferenceException
at DataAccess.Vendor.GetTableSchema() in DataAccess\Generated\Models\Vendor.cs:line 376
at DataAccess.Vendor.SetSQLProps() in DataAccess\Generated\Models\Vendor.cs:line 42
at DataAccess.Vendor..ctor() in DataAccess\Generated\Models\Vendor.cs:line 35
The test that I am running is basically the same as the one listed above except it's Vendors rather than Users that should be getting listed.
[Test]
public void CanListVendors()
{
VendorCollection vendors = VendorController.List(
VendorController
.Query()
.Where(Vendor.Columns.IsDeleted, false));
Assert.IsNotNull(vendors);
}
I would suggest there is a System.Web.Utility namespace, and you get this wrong error message because the compiler "thinks" he has to look inside this namespace for resolving the class.
Please check that your test project is set to target framework "Framework 4" and not "Framework 4 Client Profile".
Missing ".NET Framework 4 Client Profile" as target framework in "New Project" window
This seems to be working now. The only change I made within the project was to create a separate test project using Visual Studio's unit test capabilities. The only other explanation I can think of is that something troublesome got thrown out of memory when I rebooted the computer between yesterday evening and today.
For the benefit of anyone stumbling on this question in the future, here is a summary of the steps I took to get NUnit testing a DAL generated by SubSonic:
Create new class library project.
Add necessary references - I added the DAL, NUnit and SubSonic.
Add an App.config file so that
SubSonic knows where to find the
SubSonic service. All I did for this
was to pull out the parts in
Web.config that were related to
SubSonic.
Add a test class and start adding tests to it.
If your tests are inexplicably failing, make sure the "Copy to Output Directory" is set to "Copy if newer" for the App.config that was added, make sure the provider name in App.config matches the provider name used in the DAL classes and, if all else fails, reboot!
Do you always have SubSonic not Subsonic?
This is the relevant section from my nunit projects config file which works...
<configSections>
<section name="SubSonicService"
type="SubSonic.SubSonicSection, SubSonic"
requirePermission="false"/>
</configSections>
<SubSonicService defaultProvider="TAProvider">
<providers>
<clear />
<add name="TAProvider"
type="SubSonic.SqlDataProvider, SubSonic"
connectionStringName="TATesting"
generatedNamespace="DALTA"/>
</providers>
</SubSonicService>