{"action":"created","issue":{"url":"https://api.github.com/repos/mockito/mockito/issues/133","labels_url":"https://api.github.com/repos/mockito/mockito/issues/133/labels{/name}","comments_url":"https://api.github.com/repos/mockito/mockito/issues/133/comments","events_url":"https://api.github.com/repos/mockito/mockito/issues/133/events","html_url":"https://github.com/mockito/mockito/issues/133","id":51603458,"number":133,"title":"Mockito can't spy on object loaded in parent classloader","user":{"login":"akomisarek","id":8721789,"avatar_url":"https://avatars.githubusercontent.com/u/8721789?v=3","gravatar_id":"","url":"https://api.github.com/users/akomisarek","html_url":"https://github.com/akomisarek","followers_url":"https://api.github.com/users/akomisarek/followers","following_url":"https://api.github.com/users/akomisarek/following{/other_user}","gists_url":"https://api.github.com/users/akomisarek/gists{/gist_id}","starred_url":"https://api.github.com/users/akomisarek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akomisarek/subscriptions","organizations_url":"https://api.github.com/users/akomisarek/orgs","repos_url":"https://api.github.com/users/akomisarek/repos","events_url":"https://api.github.com/users/akomisarek/events{/privacy}","received_events_url":"https://api.github.com/users/akomisarek/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/mockito/mockito/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/mockito/mockito/labels/enhancement","name":"enhancement","color":"207de5"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2014-12-10T19:57:49Z","updated_at":"2015-07-28T08:56:51Z","closed_at":null,"body":"I have encountered issue with Mockito (I have tested this on 1.10.14) and usage of different classloaders - running tests in SBT 0,13.\r\n\r\nI have got empty class *TestClass* and following test:\r\n```Java\r\n    @Test\r\n    public void runTest() {\r\n        Mockito.spy(new TestClass(){\r\n\r\n        });\r\n    }\r\n```\r\nThis test fails with following: \r\n```\r\nCaused by: org.mockito.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null\r\n[error]     at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:238)\r\n[error]     at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378)\r\n[error]     at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318)\r\n[error]     at org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:123)\r\n[error]     at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57)\r\n[error]     at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)\r\n[error]     at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)\r\n[error]     at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)\r\n[error]     at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)\r\n[error]     at org.mockito.Mockito.spy(Mockito.java:1367)\r\n[error]     ... 56 more\r\n[error] Caused by: java.lang.reflect.InvocationTargetException\r\n[error]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n[error]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\r\n[error]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n[error]     at java.lang.reflect.Method.invoke(Method.java:606)\r\n[error]     at org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385)\r\n[error]     at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220)\r\n[error]     ... 65 more\r\n[error] Caused by: java.lang.IllegalAccessError: class TestMock$1$$EnhancerByMockitoWithCGLIB$$7c797c20 cannot access its superclass TestMock$1\r\n[error]     at java.lang.ClassLoader.defineClass1(Native Method)\r\n[error]     at java.lang.ClassLoader.defineClass(ClassLoader.java:800)\r\n```\r\nLooks like there is class loader issue - in sbt, the default classloader is the one for the sbt launcher, but you are \"run\" in a sub classloader.\r\n\r\nFollowing calls give different result: *Thread.currentThread().getContextClassLoader().getClass();* and *TestClass.class.getClassLoader().getClass();* \r\nThe second one is the parent of the first one.\r\n\r\nOf course there is no issue running this piece of code in IDE, but in my opinion this is Mockito's problem, something which could be improved. \r\n \r\nIs it possible to have this fixed in Mockito? I would say so because changing current classloader to the one used to load the class solves the issue. "},"comment":{"url":"https://api.github.com/repos/mockito/mockito/issues/comments/125509418","html_url":"https://github.com/mockito/mockito/issues/133#issuecomment-125509418","issue_url":"https://api.github.com/repos/mockito/mockito/issues/133","id":125509418,"user":{"login":"raphw","id":4489328,"avatar_url":"https://avatars.githubusercontent.com/u/4489328?v=3","gravatar_id":"","url":"https://api.github.com/users/raphw","html_url":"https://github.com/raphw","followers_url":"https://api.github.com/users/raphw/followers","following_url":"https://api.github.com/users/raphw/following{/other_user}","gists_url":"https://api.github.com/users/raphw/gists{/gist_id}","starred_url":"https://api.github.com/users/raphw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raphw/subscriptions","organizations_url":"https://api.github.com/users/raphw/orgs","repos_url":"https://api.github.com/users/raphw/repos","events_url":"https://api.github.com/users/raphw/events{/privacy}","received_events_url":"https://api.github.com/users/raphw/received_events","type":"User","site_admin":false},"created_at":"2015-07-28T08:56:51Z","updated_at":"2015-07-28T08:56:51Z","body":"The problem is the following:\r\n\r\n1. `TestClass` is an anonymous class which *javac* implements as a *package-private* class. In order to subclass such a package-private class, one must load the subclass with the same class loader as the anonymous class. Otherwise, the runtime package of the anonymous class is not visible to the mock class.\r\n\r\n2. The test case implies dependencies on different class loaders which requires using a `MultipleParentClassLoader` what breaks the first premise.\r\n\r\nI tried to fix this now by avoiding to use the actual package-private class. Strictly speaking, such an anonymous inner class does not render a type of its own, only an implementation. One could therefore strip the implemented type which is hopefully not package-private and instrument this public super type instead of the synthetic type that represents the anonymous class.\r\n\r\nHowever, spies are implemented by delegating non-stubbed invocations to the *real* method **of the spy** and not of the instance spied upon. By not subclassing the anoymous class, any method implementations of the anonymous class would be lost. Similar to Java, Mockito binds an anoymous class's implementation to the implementation's type and it is non-trivial to detach them from each other.\r\n\r\nI am afraid, this cannot be fixed without larger changes in Mockito's implementation."}}