Java not processing JUnit jar - java

I am unable to compile tests with JUnit. When I attempt to do so, I get this error:
package org.junit.jupiter.api does not exist
I get this error compiling the tests even if I put the .jar in the same directory and compile as follows:
javac -cp junit4-4.12.jar Tests.java
The contents of Test.java are:
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class Tests {
... several tests ...
It's not clear to me what the issue is, and as far as I can tell, it should work with the .jar -- it's the one from /usr/share/java, where it was installed when I installed junit.

As #DwB has already mentioned you have wrong junit version.
Here is what is jupiter in JUnit: http://junit.org/junit5/docs/current/user-guide/#overview-what-is-junit-5
In simple words JUnit Jupiter API is a set of new classes which were written and introduced in junit 5 version only. And ur trying to use 4 version.
And also i want to clarify some points.
even if I put the .jar in the same directory and compile as follows
It does not matter actually is your file in the same directory or not. Its all about it's path. If you are setting jar only by name of jar file (as you did) then your path becomes relative to your current directory from where u execute javac command. You can just use absolute path and run this command from every directory you want.
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html (this one is for windows but for other os there are only minor changes in path writing)
If you get errors like package does not exist, classnotfound or anything similar then such kinds of errors almost always mean you have something wrong with your classpath or dependencies. In your case you simply had wrong version.
Now about finding necessary deps. In java world one of the main places for dependencies is maven central. Almost every opensource library can be found there and maven by default uses this repository to find and load dependencies (in your case these are jars) from there. Also you can use it to get necessary jars manually by simply using it's UI (https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api/5.0.0). There is download jar button.
Now if you know package or class but do not know in what dependency (jar for simplicity) it is located. In this case you can use http://grepcode.com or other resources which allow to search within available source code withit different repositories. In most cases this work. With juniper i did not manage to find smth there but in other cases this may help) Or the most simple case is just google package and in most cases it also will help to define entry point.
Now about solving ur issue. It seems that you will need as api as implentation. You will definitely need this one https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api/5.0.0 but it seems that you will need juniper-engine too. First try adding only API and then just go on adding necessary libraries according to errors. You can add multiple jars to cp (read provided class path guide from oracle).

Related

Java modules in IntelliJ and adding require java.ws.rs gives bizarre error

We have maven apps that until recently were on JDK8. We just upgraded them to JDK11 and are trying to take advantage of the JPMS from JDK9 by making our utility libraries into modules.
We originally had this kind of path:
utils/some-library1/src/main/java/com/company/team/utils/lib1/Util1.java
There, java is the "source root".
So a colleague placed the module-info.java file in the lib1 folder and declared it thus:
module utils.lib1 {
exports com.company.team.utils.lib1;
}
From the command line that builds and works, so he assumes everything is all module-y goodness.
But when I opened in Intellij, it had an ugly red line and the message said I should move it to source root. It then moved it to the "java" folder above. Fair enough.
That caused me to dig around trying to find out more about this JPMS that my colleague had implemented. After a lot of searching and experiments, I also determined that the "java" folder, as "source root", should be renamed to the name of the module ("utils.lib1"). So now I have these two files:
utils/some-library1/src/main/utils.lib1/module-info.java
utils/some-library1/src/main/utils.lib1/com/company/team/utils/lib1/Util1.java
And even Intellij is happy. Hooray! So I refactor all the other libraries. Suddenly I hit a major snag in let's call it lib2 with this line:
module utils.lib2 {
exports com.company.team.utils.lib2;
requires java.ws.rs;
}
Intellij flags the module with the red error squiggle again, this time saying:
Module 'utils.lib2' reads package 'javax.activation' from both 'jakarta.activation' and 'jakarta.activation'
I did some digging and found out the following:
java.ws.rs pulls in one of the following (it depends on which app):
javax.ws.rs-api-2.1.1.jar
jakarta.ws.rs-api-2.1.6.jar
Their module-info.java files contain this line:
requires transitive java.xml.bind;
Which pulls in one of:
jakarta.xml.bind-api-2.3.2.jar
jakarta.xml.bind-api-2.3.3.jar
jaxb-api-2.4.0-b180830.0359.jar
Which all have this line:
requires transitive jakarta.activation;
And that's where I give up. Our libraries are big hefty things that are hard to parse completely, so to simplify I created a maven app with just one class and all it does is import javax.ws.rs.core.Link.
And IntelliJ still gives that crazy error that I can't figure out and Google has been adamant in refusing to tell me.
Is it really broken or is Intellij just as confused as I?
I gave the long story both to show what we've done and to let you know that I'm very new to modules. So if it's a simple thing, please excuse me. I am just stumped though.
Additionally, are there any obvious tests one can perform at the command line to validate module configuration?
I've had inconsistent luck with jdeps, javac, and actually running as indicators of problems.
My suspicion is that things only work now because they're all in the unnamed module. But I need to get everything working if I'm going to convince anyone to change it.
EDIT
This question was reported as already answered, but that is incorrect. The suggested link deals with two different packages (A & B) importing package X. But in my case, the error is that the same package (A & A) imports package X. And this is done a few transitives down, so I have no control over the imports and can't see how to do an exclusion. Also, this problem can be repeated with just single requires statement in module-info.java!
Plus, there is a second question here that is also important that has not been addressed: how to validate the module configuration from command line (without involving the IDE at all).
I also determined that the "java" folder, as "source root", should be renamed to the name of the module
No, it should not. The java source root should be left as is but you must create a package name corresponding to your module name, so it should be /src/main/java/ - source root and then utils/lib1 directory - whidh would be the package.
I came across exact same warning in Intellij and it was genuine. In my case the collision was coming from three separate dependencies using same module name (i.e. 'jakarta.activation'):
'jakarta.activation:jakarta.activation-api:1.2.2'
'javax.activation:javax.activation-api:1.2.0'
'com.sun.activation:jakarta.activation:1.2.2'
It got it resolved for my project by applying explicit exclusions on dependencies which were pulling the last two.

Eclipse error: “The import ... cannot be resolved”

I know I am asking the very popular question. But I can not find the solution to the problem. I have a sandbox to which I added a code of the unit test MulticurveBuildingDiscountingDiscountAUDTest.java file and commented it.
Then I added the main method and I could successfully run the program (print something in a console).
Finally, I uncommented the code of the MulticurveBuildingDiscountingDiscountAUDTest.java file and I saw the following error:
The import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedONMaster cannot be resolved.
And further in the code:
GeneratorSwapFixedONMaster cannot be resolved
I know that this import is located in the og-analytics src/test/java location, which I believe is not listed anywhere in the build path. I believe the problem is with a build path options and specially with classes like GeneratorSwapFixedONMaster which were created specially for tests. I have been playing around with cleaning, rebuilding projects, reinstalling and as a result updating the JRE. I have visited these Import *** cannot be resolved [duplicate] and these Eclipse error: “The import XXX cannot be resolved” questions.
Do you know what shall I do to cure the following error?
I have many problems with other imports from the original MulticurveBuildingDiscountingDiscountAUDTest.java file as well.
Update: #1 is a location of my file. #2 is the location of classes this project uses. The MulticurveBuildingDiscountingDiscountAUDTest.java file is taken from the src/test/java
Update 2: one may see that in Libraries I have included all the dependencies I might need (at least I do not know what else to add). The Maven Dependencies contains the hole og-analytics package:
You included the source (src) folder og-analytics/src/main/java which contains the *.java files instead of the classes (bin or classes) folder with the *.class files (in your case, probably og-analytics/target/classes).
But instead using Add Class Folder... you should add the project og-analytics in the tab Projects. Or even better, in the Maven pom.xml file add the dependency to the project og-analytics like you did for og-util.
I know that this import is located in the og-analytics src/test/java location, which I believe is not listed anywhere in the build path.
Perfectly explains your problem. In order to import any class, you must either have the source in your build path, or some directory that contains a compiled version of that class. It is that simply.
The answer is: get clear on your project setup. If you intend to use classes from somewhere, you have to make them available somehow. Otherwise it will not work. In your case: if your tests want to make use a certain thing - then you should probably add that "thing" to your test project (you should avoid putting test-only stuff to your "product" projects).
That is all there is to this.

Running a code with JUnit Test Cases

I have checked out a code from CVS and need to make changes to it. The code has 2 folders
Java
Test
The later has JUnit test cases. I'm not very familiar with JUnit but as far as my understanding is, the classes are duplicated in JUnit as class names. That's why I get the error in the test folder.
Class "xxxxx" already exists
I'm not sure how do I run this project without removing the folder test. Is there a way I can make eclipse ignore the JUnit test cases for now?
Go into the properties of the Eclipse project, open Java Build Path / Source and remove folder Test. Eclipse will then ignore the sources in that folder.
Test and normal java classes are merged together during build time, your error happens because the test classes have the exact same name as the normal classes. You should rename your test cases with some kind of prefix like Test to prevent them conflicting.
Doing things to work around the problem will only conflict later when you are changing the build platform, maybe your current build platform accepts it, but your future platform/editor may not, and then you have the real problems.

How to run Tests when developing javaagents?

I'm trying to fiddle with Foursquare's HeapAudit, and am attempting to set it up using IntelliJ IDEA. I have managed to get it to build just fine, using the dependencies from the pom.xml.
However, when I actually try to run the JUnit tests, basically all of them fail. I'm guessing this is because using HeapAudit requires the JVM to be started with it as a -javaagent, according to the github:
$ java -javaagent:heapaudit.jar MyTest
Presumably the tests would pass if I put this line in, and referenced the heapaudit.jar i downloaded/built earlier. However, it seems to me that if I make changes the the source, I'm gonna need to re-package this silly .jar file in order to see if it works.
Is there any way of running the tests with a -javaagent without going through the whole rigmarole of compile -> package-into-jar every testing cycle? Perhaps getting IntelliJ to attached the newly-compiled .class files as a -javaagent before running the tests?
1) Have a jar just with a META-INF/MANIFEST.MF
The manifest must be properly configured with Premain-Class and other attributes. The jar doesn't need any other files. Use this jar with the -javaagent. Provided that the agent classes are in the classpath, the agent will start normally.
This might fail when using maven-surefire-plugin with forkMode=never because by default the application classes are loaded in a child ClassLoader.
Works fine with Eclipse and Intellij.
If doing this, double check the manifest syntax (once I spent a long time to figure out that a package name was wrong).
2) Use ea-agent-loader
It will allow you to load the agent (any agent) in runtime (it uses VM.attach()). However the VM.attach() sometimes disrupts debugging and breakpoints might fail to trigger.
It will have the same issues with the surefire in forkMode=never
3) Load the agent in runtime.
Write your on code to load the agent in runtime. And call it from your #BeforeClass You will still need a jar (which you can generate in runtime if you want).
Just you need to call this (only once):
AgentLoader.loadAgentClass(YourAgentClass.class.getName());

Java: Resolve namespace conflict

We have a jar that we lost the source code to. I decompiled the jar and created new source from it. I want to then verify that the source code and the old jar have the same behavior. I am writing unit tests to do the verification the problem is that they both have same namespace / class name so I do not know how to disambiguate the old jar and the new source code. What can I do or is it impossible?
You need to only have one version on the class path at once to guarantee that you are running that version of the code. Develop your unit test separate from the code so you can drop in either version.
Give the new source a temporary namespace for testing purposes. Then instead of import, you can refer your new classes as:
com.yourfirm.test.packagename.TheClassName
the old ones can be simply imported and refered to as TheClassName. This way you can tell by looking at your test cases which is which.
Or simply run the tests with -cp oldpackage.jar and then -cp newpackage.jar.
It's possible, but you have to mess around with class loading. Instead of putting either of the jars on the classpath, you'll need to load them at runtime. Check out JCL for a library to allow you to do this. (Disclaimer: I have never used JCL.)
Basically, each test would have to load the class from the old JAR, grab the results of the method you're testing, then unload that JAR, load up the new one, run the same method against the new version, and compare the results.
I'd change which classes are being tested at runtime with the classpath. This approach would be less error-prone in terms of ensuring that you're running the same test code against both binaries. Otherwise you introduce more complexity around whether the tests are correct.
It sounds like you are trying to execute the tests against both jars at the same time. I don't know of a way to disambiguate the old/new jars if they are both in the classpath.
If your unit tests output results to stdout/stderr, you could run the tests against the original jar and save the results. Then run the tests against the new jar and save the results in a separate file. Then diff the files.
Another approach would be to refactor the new source code so that it has a unique namespace. You could then test against both jars at the same time, but it could be a lot of work to make existing programs use the new jar.
If you run your tests via ant (Junit-task), you can control the ant classpath seperately for both runs (once via jar, once via fileset of classes).

Categories