{"action":"created","issue":{"url":"https://api.github.com/repos/mockito/mockito/issues/152","labels_url":"https://api.github.com/repos/mockito/mockito/issues/152/labels{/name}","comments_url":"https://api.github.com/repos/mockito/mockito/issues/152/comments","events_url":"https://api.github.com/repos/mockito/mockito/issues/152/events","html_url":"https://github.com/mockito/mockito/issues/152","id":53251544,"number":152,"title":"Mockito 1.10.x timeout verification needs JUnit classes (VerifyError, NoClassDefFoundError)","user":{"login":"bric3","id":803621,"avatar_url":"https://avatars.githubusercontent.com/u/803621?v=3","gravatar_id":"","url":"https://api.github.com/users/bric3","html_url":"https://github.com/bric3","followers_url":"https://api.github.com/users/bric3/followers","following_url":"https://api.github.com/users/bric3/following{/other_user}","gists_url":"https://api.github.com/users/bric3/gists{/gist_id}","starred_url":"https://api.github.com/users/bric3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bric3/subscriptions","organizations_url":"https://api.github.com/users/bric3/orgs","repos_url":"https://api.github.com/users/bric3/repos","events_url":"https://api.github.com/users/bric3/events{/privacy}","received_events_url":"https://api.github.com/users/bric3/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/mockito/mockito/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-01-02T13:02:35Z","updated_at":"2015-01-03T14:38:55Z","closed_at":null,"body":"If JUnit is not on the classpath and mockito is version 1.10.x (as of now 1.10.1 up to 1.10.19) and the code is using the timeout verification which is not supposed to be related to JUnit, then the JVM may fail with a `VerifyError` or a `NoClassDefFoundError`.\r\n\r\nThis issue has been reported on the [mailing list](https://groups.google.com/forum/#!topic/mockito/A6D7myKiD5k) and on [StackOverflow](http://stackoverflow.com/questions/27721621/java-lang-verifyerror-with-mockito-1-10-17)\r\n\r\nA simple test like that with **TestNG** (and no JUnit in the class path of course) exposes the issue:\r\n\r\n```\r\nimport org.testng.annotations.Test;\r\nimport java.util.Observable;\r\nimport static org.mockito.Mockito.*;\r\n\r\npublic class VerifyErrorOnVerificationWithTimeoutTest {\r\n    @Test public void should_not_throw_VerifyError() {\r\n        verify(mock(Observable.class), timeout(500)).countObservers();\r\n    }\r\n}\r\n```\r\n\r\nWith TestNG 5.13.1, the stack trace is :\r\n\r\n```\r\njava.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature: (Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function\r\n\tat org.mockito.verification.Timeout.<init>(Timeout.java:32)\r\n\tat org.mockito.verification.Timeout.<init>(Timeout.java:25)\r\n\tat org.mockito.Mockito.timeout(Mockito.java:2103)\r\n\tat com.example.UserServiceImplTest.test(UserServiceImplTest.java:26)\r\n```\r\n\r\nTestNG includes a dependency on JUnit 3.8.1, which has the `junit.framework.ComparisonFailure`, but the JVM cannot perform the linking at runtime (`VerifyError` extends `LinkageError`), probably because for the JVM there's some incompatible changes in this class between version 3.x and 4.x.\r\nNote that Mockito is compiled against JUnit 4.x. This also reveal that Mockito is not anymore compatible with JUnit 3.x.\r\n\r\nWith TestNG 6.8.13, the stack trace is :\r\n\r\n```\r\njava.lang.NoClassDefFoundError: junit/framework/ComparisonFailure\r\n\tat java.lang.ClassLoader.defineClass1(Native Method)\r\n\tat java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)\r\n\tat java.lang.ClassLoader.defineClass(ClassLoader.java:621)\r\n\tat java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)\r\n\tat java.net.URLClassLoader.defineClass(URLClassLoader.java:283)\r\n\tat java.net.URLClassLoader.access$000(URLClassLoader.java:58)\r\n\tat java.net.URLClassLoader$1.run(URLClassLoader.java:197)\r\n\tat java.security.AccessController.doPrivileged(Native Method)\r\n\tat java.net.URLClassLoader.findClass(URLClassLoader.java:190)\r\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:306)\r\n\tat sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)\r\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:247)\r\n\tat org.mockito.verification.Timeout.<init>(Timeout.java:32)\r\n\tat org.mockito.verification.Timeout.<init>(Timeout.java:25)\r\n\tat org.mockito.Mockito.timeout(Mockito.java:2103)\r\n\tat com.example.UserServiceImplTest.test(UserServiceImplTest.java:26)\r\nCaused by: java.lang.ClassNotFoundException: junit.framework.ComparisonFailure\r\n\tat java.net.URLClassLoader$1.run(URLClassLoader.java:202)\r\n\tat java.security.AccessController.doPrivileged(Native Method)\r\n\tat java.net.URLClassLoader.findClass(URLClassLoader.java:190)\r\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:306)\r\n\tat sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)\r\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:247)\r\n\t... 49 more\r\n```\r\n\r\nIndeed JUnit is not anymore a dependency of TestNG.\r\n\r\nIn this specific case the issue is that the `Timeout` class wraps a `VerficationOverTimeImpl` that uses in try/catch block the exception `org.mockito.exceptions.verification.junit.ArgumentsAreDifferent` which extends `junit.framework.ComparisonFailure`.\r\n\r\nAt this time it seems to be the only place where JUnit is needed, this affect the following public API : \r\n\r\n```java\r\nMockito.timeout(...)\r\nMockito.after(...)\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/mockito/mockito/issues/comments/68596789","html_url":"https://github.com/mockito/mockito/issues/152#issuecomment-68596789","issue_url":"https://api.github.com/repos/mockito/mockito/issues/152","id":68596789,"user":{"login":"bric3","id":803621,"avatar_url":"https://avatars.githubusercontent.com/u/803621?v=3","gravatar_id":"","url":"https://api.github.com/users/bric3","html_url":"https://github.com/bric3","followers_url":"https://api.github.com/users/bric3/followers","following_url":"https://api.github.com/users/bric3/following{/other_user}","gists_url":"https://api.github.com/users/bric3/gists{/gist_id}","starred_url":"https://api.github.com/users/bric3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bric3/subscriptions","organizations_url":"https://api.github.com/users/bric3/orgs","repos_url":"https://api.github.com/users/bric3/repos","events_url":"https://api.github.com/users/bric3/events{/privacy}","received_events_url":"https://api.github.com/users/bric3/received_events","type":"User","site_admin":false},"created_at":"2015-01-03T14:38:55Z","updated_at":"2015-01-03T14:38:55Z","body":"@ferstl You are correct, the assignment is the issue here for the JUnit 3.x compatibility. Yet I wonder if we even care about JUnit 3 nowaday, especially with the upcoming Mockito 2.x.x were API incompatibility is to be somehow expected.\r\n\r\nAnyway I implemented a test that ensure that pure mockito API don't have JUnit dependency. The good news is that only `VerificationOverTimeImpl` is affected. I started a fix branch yesterday for this issue where I was thinking about the same kind of tricks to avoid future mess up."}}