TestNG tests execution against JDK 9 module causes InaccessibleObjectException - java

I'm trying to transform the following library into Java 9 module: https://github.com/sskorol/test-data-supplier
Followed this guide: https://guides.gradle.org/building-java-9-modules
After some manipulations and refactoring (couldn't manage lombok issues, so just temporary removed it), I have the following module-info.java:
module io.github.sskorol {
exports io.github.sskorol.core;
exports io.github.sskorol.model;
requires testng;
requires vavr;
requires streamex;
requires joor;
requires aspectjrt;
}
And it even compiles / builds in case of tests' skipping.
However, when I try to run a test task, I'm getting the following exception:
org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for Gradle Test Executor 2.
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:63)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy1.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:120)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: org.testng.TestNGException:
Cannot instantiate class io.github.sskorol.testcases.DataSupplierTests
at testng#6.11/org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:31)
at testng#6.11/org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:410)
at testng#6.11/org.testng.internal.ClassHelper.createInstance(ClassHelper.java:323)
at testng#6.11/org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:126)
at testng#6.11/org.testng.internal.ClassImpl.getInstances(ClassImpl.java:191)
at testng#6.11/org.testng.TestClass.getInstances(TestClass.java:99)
at testng#6.11/org.testng.TestClass.initTestClassesAndInstances(TestClass.java:85)
at testng#6.11/org.testng.TestClass.init(TestClass.java:77)
at testng#6.11/org.testng.TestClass.<init>(TestClass.java:42)
at testng#6.11/org.testng.TestRunner.initMethods(TestRunner.java:423)
at testng#6.11/org.testng.TestRunner.init(TestRunner.java:250)
at testng#6.11/org.testng.TestRunner.init(TestRunner.java:220)
at testng#6.11/org.testng.TestRunner.<init>(TestRunner.java:161)
at testng#6.11/org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:578)
at testng#6.11/org.testng.SuiteRunner.init(SuiteRunner.java:185)
at testng#6.11/org.testng.SuiteRunner.<init>(SuiteRunner.java:131)
at testng#6.11/org.testng.TestNG.createSuiteRunner(TestNG.java:1383)
at testng#6.11/org.testng.TestNG.createSuiteRunners(TestNG.java:1363)
at testng#6.11/org.testng.TestNG.runSuitesLocally(TestNG.java:1217)
at testng#6.11/org.testng.TestNG.runSuites(TestNG.java:1144)
at testng#6.11/org.testng.TestNG.run(TestNG.java:1115)
at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:129)
at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:88)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
... 25 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public io.github.sskorol.testcases.DataSupplierTests() accessible: module io.github.sskorol does not "exports io.github.sskorol.testcases" to module testng
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:192)
at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:185)
at testng#6.11/org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:22)
... 48 more
It seems a bit confusing to me, as io.github.sskorol.testcases is a part of src/test/java and there's no module-info for tests. So I can't export this package to TestNG. Have an assumption that the root cause in a TestNG reflection usage within ObjectFactoryImpl against test classes.
Does anyone have any idea how to workaround it?
Environment: JDK 9 (build 9+181), Gradle 4.1, TestNG 6.11

Have an assumption that the root cause in a TestNG reflection usage within ObjectFactoryImpl against test classes.
It's one of two causes, yes. The other is that, apparently, Gradle runs your tests as a module. As you point out, there's no module descriptor for your tests. Gradle may use --patch-module to add the tests to the module containing the production code.
This question and answer provides a lot of background information and possible fixes. As a short term fix, I recommend to add opens io.github.sskorol.testcases to your production code's module descriptor. Judging by its name, I'd guess there is no such package yet, so you'd either have to rename or add a dummy class (I would prefer the former).
I would also take this issue to a Gradle mailing list or bug tracker. Unless we've overlooked something (entirely possible), Gradle's behavior is very unfortunate because it would require adapting the production code's module descriptor to the test code's needs.

If the tests are in the same package as the module under test then they need to be compiled (with --patch-module) so that they are compiled "as if" they are part of the module. The references to TestNG types in the tests means that that --add-reads io.github.sskorol=testng will be needed too.
Running is similar. The tests need to be run "as if" they are in module io.github.sskorol. This means running with:
--patch-module io.github.sskorol=<testclasses> \
--add-reads io.github.sskorol=testng
Additionally, you may need to export or open the packages with the tests to TestNG. This will come down to whether the test classes and methods are public in an exported package. To avoid scanning, the simplest is to open the all packages containing tests to TestNG, e.g.
--add-opens io.github.sskorol/io.github.sskorol.core=testng \
--add-opens io.github.sskorol/io.github.sskorol.core.internal=testng
(.internal is just a filler for a non-exported package in the module)
All this might look complicated but it's something that the Maven Surefire plugin and also Gradle should do.

Did some tricks suggested by #AlanBateman, who gave me a valid direction.
Finally, I came up with the following configuration:
module-info.java
module io.github.sskorol {
exports io.github.sskorol.core;
exports io.github.sskorol.model;
opens io.github.sskorol.utils to joor;
requires testng;
requires vavr;
requires streamex;
requires joor;
}
build.gradle
test {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'ALL-MODULE-PATH',
'--add-opens', 'io.github.sskorol/io.github.sskorol.testcases=testng',
'--add-opens', 'io.github.sskorol/io.github.sskorol.testcases=joor',
'--add-opens', 'io.github.sskorol/io.github.sskorol.datasuppliers=joor',
'--add-opens', 'io.github.sskorol/io.github.sskorol.datasuppliers=testng',
'--add-opens', 'java.base/java.util=streamex',
'--add-opens', 'java.base/java.util.stream=streamex',
'--patch-module', "$moduleName=" + files(sourceSets.test.java.outputDir).asPath
]
classpath = files()
}
}
Both testng and joor required access to my test packages. So --add-opens flag did the trick. streamex module also had concerns accessing java.base packages.
Note that in comparison with original Java 8 code I had to remove lombok and aspectj dependencies, as I couldn't manage to fully resolve all the issues occurred after migration.
Another problem I've faced with was related to SPI testing. According to docs I've read, in Java 9 SPI implementations should be listed within module-info.java instead of META-INF/services. But it doesn't seem to be a solution, when implementation class is located in one of test packages, as again test is not a module. Just wondering if there's some jvmflag for replacing provides ... with ... syntax, and doing the same trick as with --add-opens. Any thoughts would be appreciated.
Full implementation, modified to support Java 9, could be found here.

Related

Gradle and Spring-bootRun can not find my class

Having two Projects:
Classic (Having main class)
Advanced
Id like to have the Advanced to have all classes the Classic have. But as I run Advanced/gradle bootRun all the Advanced classes seems to be missing.
Advanced/src/main/java/foo/Bar.java:
package foo;
public class Bar{
//empty
}
Classic/src/main/java/foo/Classic.java:
package foo;
public class Classic {
public static void main(){
try {
Class.forName("foo.Bar");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Exception:
java.lang.ClassNotFoundException: foo.Bar
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:340)
at foo.Classic.main(Classic.java:14)
java.lang.ClassNotFoundException: foo.Bar
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:144)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:340)
at foo.Classic.main(Classic.java:14)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
I have this in my Advanced/build.gradle:
...
dependencies{
...
implementation project(':classic')
...
}
...
Important info from Comments:
Jacob G.
I talked for awhile with OP in one of the chat rooms, and I've discovered a few things. When attempting to build the Advanced project with Gradle, it reports 50+ compilations errors regarding package not found:, referring to packages in the Classic project. Also, Classic and Advanced do not share a root project, so I have a feeling that attempting to depend on project(':classic') is futile. OP stated that commits can only be made to Advanced, so it may not be possible to fix the issue at all. For anyone curious, OP is also not using an IDE.
Statement of respect
I made an edit to the question, I added an limitation. It was an very important edit that I can only commit changes in Advanced. Because of the fact that I have no experience in gradle I was not aware of the imporance of this additional information. I feel sorry for the late limitation, feel comfort for the courtesy and hope for understanding.
As far as I could understand from the question we are dealing with a multiple project scenario. In this case the multi project builds documentation tells us that it is necessary to have a settings.gradle in the folder that contains the two projects:
then it is possible to run both the projects without cd change directory into the specific folder , but directly from the multi-project root by command: gradle advanced:bootRun
EDIT according to 20200610 EDIT of the question acknowledging the specification: commits can only be made to the Advanced project.
we can still get a solution but in this scenario ( actually not a gradle multi-project)
no need to have a settings.gradle at the parent directory level of Advanced; it satisfy the requirement of not being able to commit outside of Advanced
it doesn't matter how it's built the Classic project, we don't care about it since we can't commit on it
we can't use in Advanced/build.gradle the implementation project(':classic') as dependency since this works only in real gradle multi-project scenarios ; in here we must use a file dependency or another type of dependecy available for the user's development environment.
In this case it is possible to run the Advanced project by cd Advanced then , from the Advanced directory run th command: gradle bootRun
why it works ?
..In order to better understand how it works lets's inspect the
SystemClassLoader's current paths by adding this lines of code in Advanced/src/main/java/com/example/springboot/Application.java
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
System.out.println(url.getFile());
}
the output is:
<multi-project-root>/Advanced/build/classes/java/main/
<multi-project-root>/Advanced/build/resources/main/
<multi-project-root>/Classic/build/libs/Classic-0.0.1-SNAPSHOT.jar
~/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring
... [suppressed many othe spring devtools and gradle related caches ]
this allow both the Advanced and the Classic classes to find each others
source code of a proof of concempt
The POC source-code new branch has been updated accordingly
What you need is Gradle's composite build. See my POC project.
The advanced project includes the classic project by this line
The advanced/App.java calls classic.App.main, And the classic.App class can load foo.Bar from the advanced project. No need to do a commit to classic project.
Execute "gradlew run" in the advanced folder
to see how it works.
I also had the same project structure as the one you have so by making below-mentioned changes it works fine for me :
Entry in build.gradle file
compile project(':Classic')
Entry in settings.gradle
include ':Classic'
project(':Classic').projectDir = new File(settingsDir, '../../libs/Classic')
I hope this will work for you too and yes don't forget to rebuild your grade project after making these changes.

Gradle unable to run JUnit tests with useJUnitPlatform()

My project is a Gradle dependent JavaFX project using Java JDK 11. The project was made using the default structure of a Gradle project. So under src it has "main" and "test", each consisting of a "java" and a "resource" directory.
For setting up a CI pipeline with Jenkins it is a requirement that gradlew test runs all tests in the same way my IDE (IntelliJ) so far has. The funny thing is, I have not been able to get this to work after hours of trying.
In the IntelliJ run configuration it tests "all in package", within the .test package, and this works just fine (click for screenshot) Below are all the relevant parts of the build.gradle file, please note that I have left out all unrelated parts for simplicity.
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
}
test {
useJUnitPlatform()
}
application {
mainClassName = 'FP.EDM.main/edm.Main'
}
Whenever I run the gradlew test command I get the following two errors:
java.lang.RuntimeException: Unable to parse --add-opens <module>/<package>: FP.EDM.main/
Could not write standard input to Gradle Test Executor 1.
java.io.IOException: The pipe is being closed
at java.base/java.io.FileOutputStream.writeBytes(Native Method)
at java.base/java.io.FileOutputStream.write(FileOutputStream.java:354)
at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
at org.gradle.process.internal.streams.ExecOutputHandleRunner.forwardContent(ExecOutputHandleRunner.java:67)
at org.gradle.process.internal.streams.ExecOutputHandleRunner.run(ExecOutputHandleRunner.java:52)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.base/java.lang.Thread.run(Thread.java:834)
Another approach I have tried is to use the useJUnit() command instead of useJUnitPlatform(). At first sight this seems to work perfectly fine however when I use this no tests are found at all. My assumption is that the default module for tests is not set correctly. However I have found no way to set this or no mention of this anywhere online. Please let me know what your thoughts are :)
PS. I would much rather not downgrade to JUnit 4.x since that would require me to rewrite all these (working) tests.
Alright I solved the issue, I'm not quite sure what exactly caused it but it had something to do with the module-info for both the main and test modules. I decided to remove both for the time being and it runs like it should.
Edit:
After days of looking around I got it figured out at last. Adding a module-info.java encapsulates a module and it's dependencies. Because this project applies the gradle-modules-plugin I wouldn't recommend using the same plugin again as it could cause issues though I have not experimented with this myself.
What is the way to go then? Well there are two options:
-Ignore the module-info.java > this can be done in the build.gradle file, for an example of that solution have a look at this
-Specify a module-info.test > this is a way to apply certain dependencies, mine looks like the following:
--add-modules
org.junit.jupiter.api
--add-reads
FP.EDM.main=org.junit.jupiter.api
Please do keep in mind: this file format should go in the root of your source, all my test files were in a different directory in the root, as I didn't get it to work in the root (though that could just be me).
For further reading there is this Git issue which helped me solve it in the first place or this excellent blog by Sormuras which explains a lot

How to prevent java.lang.IllegalAccessError with JDK11?

We receive the follow exception in our test system. Any idea how we can prevent this exception for example with a command line switch. And any idea how this exception can occur?
Can the completely access check be disabled in a test system that use intensively reflection and class loading?
java.lang.IllegalAccessError: class java.io.File (in module java.base) cannot access class javax.print.PrintException (in module java.desktop) because module java.base does not read module java.desktop
at java.io.File.exists(File.java)
at jdk.internal.loader.URLClassPath$FileLoader.getResource(URLClassPath.java:1199)
at jdk.internal.loader.URLClassPath.getResource(URLClassPath.java:314)
at jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:697)
at jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:398)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:67)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:66)
Try to run it by adding the following command argument.
--add-reads java.base=java.desktop
We solve the problem by updating JMockit version 1.31 with the current version 1.44. It look like the old version is not compatible with the current version.

class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package [duplicate]

I am using hamcrest 1.3 to test my code. It is simply a die. I am trying to test it to make sure the number generated is less than 13. I had a print statement that printed what the number generated was. The number generated was always less than 13 but the test always failed. Is there something I am doing wrong?
This is the code I am testing.
import java.util.Random;
public class Die {
private int numSides;
Random rand;
public Die(int numSides){
this.numSides = numSides;
rand = new Random(System.currentTimeMillis());
}
public int roll(){
return rand.nextInt(numSides) + 1;
}
}
And this is my test code.
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;
public class DieTest {
#Test
public void testRoll() {
Die x = new Die(12);
assertThat(x.roll(), is(lessThan(13)));
}
}
Edit: This is the failure stack trace.
java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(Unknown Source)
at java.lang.ClassLoader.preDefineClass(Unknown Source)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at DieTest.testRoll(DieTest.java:12)
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:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)
This is the site that help me solve the problem.
http://code.google.com/p/hamcrest/issues/detail?id=128
The hamcrest.jar needs to go before the Junit library in the build path.
I just removed JUnit library from my project configuration. I still can run the tests as JUnit is also included in my pom file. So the solution just use the library from Maven.
In my Eclipse inside Project settings in Java Build Path section, Libraries I have previously added internal JUnit library which uses JUnit version 4.8 and hamcrest-core version 1.1. I believe that that was causing this error in my case.
I leave this bit of information here, maybe somebody else would benefit from my experience.
If you are using a Maven project, simply remove the Junit library from the build path and instead import Junit and Hamcrest separately via POM.
Use junit-dep.jar rather than junit.jar- this is JUnit minus its dependencies. Junit.jar contains an old version of Hamcrest.
First of all make sure that you have added JUnit dependency in POM.xml file.
Now, right click on the project and go to properties, select Java build path and select Libraries tab.
In my case there were Maven dependencies, JRE and Junit4 libraries. And I just removed Junit library and it works for me. Or one can also reorder the libraries as due to build order of Hamcrest and JUnit4 the problem was occurring.
Johan Mark (above) suggested to
rename the file $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar to something like *.bak or remove the file."
Renaming/removing the file caused my Eclipse Junit library to stop working, but replacing the JAR file with a copy of the same version from my Maven repo made the certificate problem go away.
(As someone on Google remarked, the Eclipse Junit copy of hamcrest has a cert issue but the Maven copy does not...)
If you are Using Maven:
Steps:
Add Latest Hamcrest Dependency into POM, from here https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all
Add Latest JUnit Dependency into POM,from Here
https://mvnrepository.com/artifact/junit/junit
Remove Any JUnit libraries from the Build path.
As Shown here
and Here
After you have Completed all above steps , Refresh your Project and Run.
I was getting the same exception. Like beachw08 recommended, I referred to:
http://code.google.com/p/hamcrest/issues/detail?id=128
One of the posts said:
rename the file $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar to something like *.bak or remove the file.
I did this and it solved my problem.
If you get the following exception "java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package", ensure that the hamcrest jar is before the Junit library in the build path. You can configure the order in the project properties under Java Build Path on the Order and Export tab.
click below image link for more clarity :
http://i.stack.imgur.com/Y5R15.png
Removed the JUNIT 4 library from the libraries tab on Eclipse -> Java Build path and it worked.
I had the same problem.
Right Click on the project / Order and Export/ move up your hamcrest lib to the first position, for some reason it has to go first than your Junit lib
I resolved this problem by removing Junit4 library from the Build Path and added TestNG Library to the build path and imported TestNG annotations instead of Junit4 annotations in my java program.
With eclipse, I had the same issue but with mvn commandline was working. Solved it by removing Junit into the build path, not in order and export. Above example is before removing it.
I had the same problem as detailed here. I believe the problem comes down to the junit4 jar file. If, under eclipse pom editor, you look at the junit4 Hierarchy you will see that it has a dependency on hamcrest-core (i.e. hamcrest-core will, by default, be pulled in on compile). In my unit test code I use the hamcrest collection Matchers (org.hamcrest.collection). These aren't included in the core jar and I set up a dependency on hamcrest-all in the pom. Doing this duplicates the hamcrest-core inclusion and appear to leave you open to a version mismatch with the junit hamcrest-core dependency and hence the security exception. I removed the hamcrest-all dependency and replaced it with hamcrest-library and the exception went away.
If you only use core hamcrest then you should not set up your own dependency and rely on the version junit pulls in. Alternately, as suggested in another comment, use junit-dep to strip out the junit dependency and then include hamcrest-all.
i recently had this problem with eclipse and Junit.
To solve this, i did that:
1 - Download the latest hamcrest-all jar from here : https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/hamcrest/
2- Go on the eclipse installation folder: eclipse/plugin/ and find the org.hamcrest...jar
3- make a backup of the step 2 jar and replace it by the step 1 jar (rename it same as the jar step 2).
4- restart eclipse
After that, my issue was solved.
When trying to solve this problem for your particular context, keep in mind the stack trace above is merely a symptom. The solutions may work for some people, but not others.
For instance:
Putting the Hamcrest JAR before the JUnit JAR in the classpath will work in situations where the version of JUnit in use (older) contains Hamcrest classes
Overlaying the version of Hamcrest used internally by Eclipse with a 'stock' version that's been renamed to match the internal version may work if no other Eclipse plugin bundle uses manifest information in the original internal JAR
In my case, the symptom above was caused by a Hamcrest JAR used internally and provided by Eclipse, and when I tried to replaced it with a 'stock' renamed version, anything related to JUnit failed to load when I started Eclipse. After I reverted back to the original internal version, the SecurityException returned. The solution that worked for me was to delete the manifest in the JAR using 7-Zip. This effectively 'unsigned' the JAR and now my particular configuration works.
my environment Mac OS + eclipse, I found org.hamcrest.core_1.3.0.v201303031735.jar is in my JUnit 4,
so I can't make it forward than junit.jar.
so I delete it from path ~/.p2/pool/plugins/, then refresh project, it works.
This one resolved my issue :
Replace $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar with Maven or your project's lib's hamcrest-core-xx.jar (obviously renaming it to same name as eclipse jar)
I went into the build properties for the project and changed JUNIT from version 4 to version 3 and it works fine now.
Interestingly I still have version 4 in my pom.xml so I am inclined to think that this is an eclipse issue (I was able to build and run my tests via terminal just fine).
I did the following:
First in pom file i excluded hamcrest-core from junit dependency and used instead hamcrest-all. Second i removed from build path the eclipse JUNIT as it overrides the maven one. The ordering didn't affect my jars since the bad jar was excluded.
I had exactly the same issue. I created a new project and it resolved my issue.
just go to the project
then click on build path and click on configure build path
click on libraries check junit and remove it(note that junit and hamcrest in pom file)

hamcrest tests always fail

I am using hamcrest 1.3 to test my code. It is simply a die. I am trying to test it to make sure the number generated is less than 13. I had a print statement that printed what the number generated was. The number generated was always less than 13 but the test always failed. Is there something I am doing wrong?
This is the code I am testing.
import java.util.Random;
public class Die {
private int numSides;
Random rand;
public Die(int numSides){
this.numSides = numSides;
rand = new Random(System.currentTimeMillis());
}
public int roll(){
return rand.nextInt(numSides) + 1;
}
}
And this is my test code.
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;
public class DieTest {
#Test
public void testRoll() {
Die x = new Die(12);
assertThat(x.roll(), is(lessThan(13)));
}
}
Edit: This is the failure stack trace.
java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(Unknown Source)
at java.lang.ClassLoader.preDefineClass(Unknown Source)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at DieTest.testRoll(DieTest.java:12)
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:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)
This is the site that help me solve the problem.
http://code.google.com/p/hamcrest/issues/detail?id=128
The hamcrest.jar needs to go before the Junit library in the build path.
I just removed JUnit library from my project configuration. I still can run the tests as JUnit is also included in my pom file. So the solution just use the library from Maven.
In my Eclipse inside Project settings in Java Build Path section, Libraries I have previously added internal JUnit library which uses JUnit version 4.8 and hamcrest-core version 1.1. I believe that that was causing this error in my case.
I leave this bit of information here, maybe somebody else would benefit from my experience.
If you are using a Maven project, simply remove the Junit library from the build path and instead import Junit and Hamcrest separately via POM.
Use junit-dep.jar rather than junit.jar- this is JUnit minus its dependencies. Junit.jar contains an old version of Hamcrest.
First of all make sure that you have added JUnit dependency in POM.xml file.
Now, right click on the project and go to properties, select Java build path and select Libraries tab.
In my case there were Maven dependencies, JRE and Junit4 libraries. And I just removed Junit library and it works for me. Or one can also reorder the libraries as due to build order of Hamcrest and JUnit4 the problem was occurring.
Johan Mark (above) suggested to
rename the file $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar to something like *.bak or remove the file."
Renaming/removing the file caused my Eclipse Junit library to stop working, but replacing the JAR file with a copy of the same version from my Maven repo made the certificate problem go away.
(As someone on Google remarked, the Eclipse Junit copy of hamcrest has a cert issue but the Maven copy does not...)
If you are Using Maven:
Steps:
Add Latest Hamcrest Dependency into POM, from here https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all
Add Latest JUnit Dependency into POM,from Here
https://mvnrepository.com/artifact/junit/junit
Remove Any JUnit libraries from the Build path.
As Shown here
and Here
After you have Completed all above steps , Refresh your Project and Run.
I was getting the same exception. Like beachw08 recommended, I referred to:
http://code.google.com/p/hamcrest/issues/detail?id=128
One of the posts said:
rename the file $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar to something like *.bak or remove the file.
I did this and it solved my problem.
If you get the following exception "java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package", ensure that the hamcrest jar is before the Junit library in the build path. You can configure the order in the project properties under Java Build Path on the Order and Export tab.
click below image link for more clarity :
http://i.stack.imgur.com/Y5R15.png
Removed the JUNIT 4 library from the libraries tab on Eclipse -> Java Build path and it worked.
I had the same problem.
Right Click on the project / Order and Export/ move up your hamcrest lib to the first position, for some reason it has to go first than your Junit lib
I resolved this problem by removing Junit4 library from the Build Path and added TestNG Library to the build path and imported TestNG annotations instead of Junit4 annotations in my java program.
With eclipse, I had the same issue but with mvn commandline was working. Solved it by removing Junit into the build path, not in order and export. Above example is before removing it.
I had the same problem as detailed here. I believe the problem comes down to the junit4 jar file. If, under eclipse pom editor, you look at the junit4 Hierarchy you will see that it has a dependency on hamcrest-core (i.e. hamcrest-core will, by default, be pulled in on compile). In my unit test code I use the hamcrest collection Matchers (org.hamcrest.collection). These aren't included in the core jar and I set up a dependency on hamcrest-all in the pom. Doing this duplicates the hamcrest-core inclusion and appear to leave you open to a version mismatch with the junit hamcrest-core dependency and hence the security exception. I removed the hamcrest-all dependency and replaced it with hamcrest-library and the exception went away.
If you only use core hamcrest then you should not set up your own dependency and rely on the version junit pulls in. Alternately, as suggested in another comment, use junit-dep to strip out the junit dependency and then include hamcrest-all.
i recently had this problem with eclipse and Junit.
To solve this, i did that:
1 - Download the latest hamcrest-all jar from here : https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/hamcrest/
2- Go on the eclipse installation folder: eclipse/plugin/ and find the org.hamcrest...jar
3- make a backup of the step 2 jar and replace it by the step 1 jar (rename it same as the jar step 2).
4- restart eclipse
After that, my issue was solved.
When trying to solve this problem for your particular context, keep in mind the stack trace above is merely a symptom. The solutions may work for some people, but not others.
For instance:
Putting the Hamcrest JAR before the JUnit JAR in the classpath will work in situations where the version of JUnit in use (older) contains Hamcrest classes
Overlaying the version of Hamcrest used internally by Eclipse with a 'stock' version that's been renamed to match the internal version may work if no other Eclipse plugin bundle uses manifest information in the original internal JAR
In my case, the symptom above was caused by a Hamcrest JAR used internally and provided by Eclipse, and when I tried to replaced it with a 'stock' renamed version, anything related to JUnit failed to load when I started Eclipse. After I reverted back to the original internal version, the SecurityException returned. The solution that worked for me was to delete the manifest in the JAR using 7-Zip. This effectively 'unsigned' the JAR and now my particular configuration works.
my environment Mac OS + eclipse, I found org.hamcrest.core_1.3.0.v201303031735.jar is in my JUnit 4,
so I can't make it forward than junit.jar.
so I delete it from path ~/.p2/pool/plugins/, then refresh project, it works.
This one resolved my issue :
Replace $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar with Maven or your project's lib's hamcrest-core-xx.jar (obviously renaming it to same name as eclipse jar)
I went into the build properties for the project and changed JUNIT from version 4 to version 3 and it works fine now.
Interestingly I still have version 4 in my pom.xml so I am inclined to think that this is an eclipse issue (I was able to build and run my tests via terminal just fine).
I did the following:
First in pom file i excluded hamcrest-core from junit dependency and used instead hamcrest-all. Second i removed from build path the eclipse JUNIT as it overrides the maven one. The ordering didn't affect my jars since the bad jar was excluded.
I had exactly the same issue. I created a new project and it resolved my issue.
just go to the project
then click on build path and click on configure build path
click on libraries check junit and remove it(note that junit and hamcrest in pom file)

Categories

Resources