Setting up test inputs in eclipse - java

I have some methods that would require to execute over a java class.
For example my method receives as argument a class file, something like:
Information info = grabInformation("class_to_execute");
This method would run the "class_to_execute"and capture its output. And I would like to later assert its output with a given expected value.
My question is: how could I set up eclipse so that my test cases would find the classes that it will execute? Is adding the classes to the build path enough? Are there some variables I could set?
I don't think the CLASSPATH has anything to do with it.

If "class_to_execute" is in another project or JAR, then add it to your Build Path under Libraries. Do you have any reason to believe that's not enough? Build path == CLASSPATH for most purposes.
If you're having Build Path or CLASSPATH problems, it might be easier to debug if you do this:
Information info = grabInformation(class_to_execute.class);
If it can't find the class, then put your cursor on the error and type Control+1. Eclipse might be able to help you fix the Build Path automatically.

Related

Java not processing JUnit jar

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).

Setting classpath enviroment variable value globally

I want to be able to execute a java class from Command Prompt in windows without specifying the classpath explicitly every time I want to execute a java class, for example like this
where I execute the HelloWorld class in the "ExamplePackage" package.
I want to accomplish the same result without specifying the classpath, as follows
but this gives me an Error: Could not find or load main class HelloWorld. As I understand it, this error is caused by java not being able to locate the class since classpath has not been specified.
Now, I want to solve this problem by setting a global variable classpath value to C:\Users\UpdatusUser\Desktop\ExampleProject.
This can be accomplished, as I understand, over here
But that does not seem to solve the issue, since I still get the following result if I now use java ExamplePackage.HelloWorld
What am I doing wrong?
For a full explanation see this:
What does "Could not find or load main class" mean?
The short answer is execute the java command from the ExampleProject folder not the ExamplePackage folder.

Compile-time define in java [duplicate]

When I used to write libraries in C/C++ I got into the habit of having a method to return the compile date/time. This was always a compiled into the library so would differentiate builds of the library. I got this by returning a #define in the code:
C++:
#ifdef _BuildDateTime_
char* SomeClass::getBuildDateTime() {
return _BuildDateTime_;
}
#else
char* SomeClass::getBuildDateTime() {
return "Undefined";
}
#endif
Then on the compile I had a '-D_BuildDateTime_=Date' in the build script.
Is there any way to achieve this or similar in Java without needing to remember to edit any files manually or distributing any seperate files.
One suggestion I got from a co-worker was to get the ant file to create a file on the classpath and to package that into the JAR and have it read by the method.
Something like (assuming the file created was called 'DateTime.dat'):
// I know Exceptions and proper open/closing
// of the file are not done. This is just
// to explain the point!
String getBuildDateTime() {
return new BufferedReader(getClass()
.getResourceAsStream("DateTime.dat")).readLine();
}
To my mind that's a hack and could be circumvented/broken by someone having a similarly named file outside the JAR, but on the classpath.
Anyway, my question is whether there is any way to inject a constant into a class at compile time
EDIT
The reason I consider using an externally generated file in the JAR a hack is because this is) a library and will be embedded in client apps. These client apps may define their own classloaders meaning I can't rely on the standard JVM class loading rules.
My personal preference would be to go with using the date from the JAR file as suggested by serg10.
I would favour the standards based approach. Put your version information (along with other useful publisher stuff such as build number, subversion revision number, author, company details, etc) in the jar's Manifest File.
This is a well documented and understood Java specification. Strong tool support exists for creating manifest files (a core Ant task for example, or the maven jar plugin). These can help with setting some of the attributes automatically - I have maven configured to put the jar's maven version number, Subversion revision and timestamp into the manifest for me at build time.
You can read the contents of the manifest at runtime with standard java api calls - something like:
import java.util.jar.*;
...
JarFile myJar = new JarFile("nameOfJar.jar"); // various constructors available
Manifest manifest = myJar.getManifest();
Map<String,Attributes> manifestContents = manifest.getAttributes();
To me, that feels like a more Java standard approach, so will probably prove more easy for subsequent code maintainers to follow.
I remember seeing something similar in an open source project:
class Version... {
public static String tstamp() {
return "#BUILDTIME#";
}
}
in a template file. With Ant's filtering copy you can give this macro a value:
<copy src="templatefile" dst="Version.java" filtering="true">
<filter token="BUILDTIME" value="${build.tstamp}" />
</copy>
use this to create a Version.java source file in your build process, before the compilation step.
AFAIK there is not a way to do this with javac. This can easily be done with Ant -- I would create a first class object called BuildTimestamp.java and generate that file at compile time via an Ant target.
Here's an Ant type that will be helpful.
Unless you want to run your Java source through a C/C++ Preprocessor (which is a BIG NO-NO), use the jar method. There are other ways to get the correct resources out of a jar to make sure someone didn't put a duplicate resource on the classpath. You could also consider using the Jar manifest for this. My project does exactly what you're trying to do (with build dates, revisions, author, etc) using the manifest.
You'll want to use this:
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
This will get you ALL of the manifests on the classpath. You can figure out which jar they can from by parsing the URL.
Personally I'd go for a separate properties file in your jar that you'd load at runtime... The classloader has a defined order for searching for files - I can't remember how it works exactly off hand, but I don't think another file with the same name somewhere on the classpath would be likely to cause issues.
But another way you could do it would be to use Ant to copy your .java files into a different directory before compiling them, filtering in String constants as appropriate. You could use something like:
public String getBuildDateTime() {
return "#BUILD_DATE_TIME#";
}
and write a filter in your Ant file to replace that with a build property.
Perhaps a more Java-style way of indicating your library's version would be to add a version number to the JAR's manifest, as described in the manifest documentation.
One suggestion I got from a co-worker
was to get the ant file to create a
file on the classpath and to package
that into the JAR and have it read by
the method. ... To my mind that's a
hack and could be circumvented/broken
by someone having a similarly named
file outside the JAR, but on the
classpath.
I'm not sure that getting Ant to generate a file is a terribly egregious hack, if it's a hack at all. Why not generate a properties file and use java.util.Properties to handle it?

not able to configure cofoja on eclipse

Eclipse is up to date, cofoja too, and so are java jre/jdk.
ASM should be included in cofoja, but I downloaded the 3.3 just in case.
I followed all the procedures I could find in internet, but the first error eclipse is giving never changed from the first step: "Syntax error, insert "EnumBody" to complete BlockStatements".
The code is very basic:
import java.io.whatever;
import java.net.whatever;
import com.google.java.contract.Requires;
public class ManageSocketServerExplicit{
[...]
public ManageSocketServerExplicit(String p_ipAddress, int p_port){
#Requires("p_port >= 0")
this(p_ipAddress,p_port,10,1000);
[...]
}
}
The error is obviously at the end of the Require.
Configuration
There are several projects in the directory. Let's say that I want to use cofoja just on one of them.
The base directory is C:\svn_java\Progetti_NET, in which there is the project I want to use cofoja on, which is 'Malu'. Into it there are multiple source directories, not just a generic 'src', but the main is called 'Code', and it's the principal.
So the paths are (tried them with both slashes, nothing changes):
classoutput C:\svn_java\Progetti_NET\Malu\bin
classpath C:\svn_java\cofoja-1.1-r146.jar
sourcepath C:\svn_java\Progetti_NET\Malu\Code
Eclipse understands the namespace of cofoja, by the way: I can see the objects listed if I auto-complete them.
So 'Annotation Processing' is all set, and 'Factory Path' again contains "c:\svn_java\cofoja-1.1-r146.jar". The workspace automatically updates when there are changes, and both asmn and cofoja are in the libraries of the 'Java Build Path'.
I tried to add also the -vm command in eclipse.ini to use the jdk (C:/Program Files (x86)/Java/jdk1.7.0_21/bin), but again nothing changed.
Since the configuration is pretty simple it shouldn't be so hard to fix it, but I don't know how.
i used Cofoja with eclipse and i used this link to configure it.
However it has a missing factory path. You need to state the sourcepath too as shown in my image.
If you run it using eclipse, you have to set the run configurations of the file and add the following VM arguements
-javaagent:PATH TO JAR/cofoja.jar
And #Requires and #Ensures are method-level contracts.
You cant write it within the method. Instead you need to write it as follows
public class ManageSocketServerExplicit{
[...]
#Requires("p_port >= 0") // CONTRACT
public ManageSocketServerExplicit(String p_ipAddress, int p_port){
this(p_ipAddress,p_port,10,1000);
[...]
} }
Hope it helps :D
Ok, I understood what was wrong: after adding the source code of cofoja to the project I understood I placed the #Requires in the wrong place... The annotation #Ensures gave me this error, but I forgot about it.
:(
a very well realized tutorial: http://webcourse.cs.technion.ac.il/236700/Spring2013/ho/WCFiles/Contracts%20for%20Java.pdf

NoClassDefFoundError on command-line with new NetBeans project

I've created a new J2SE project in NetBeans, and I can run it from the IDE, but when I try to run it using Ant on the command line, I get the following problem:
<snip>
run:
[java] Exception in thread "main" java.lang.NoClassDefFoundError: IndexBuilder
[java] Java Result: 1
<snip>
Based on the snippet from project.properties below, the class should be found.
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
How do I go about fixing this?
The error you're getting means that one of the following is true:
The class IndexBuilder cannot be found on the classpath
A necessary (for class loading) dependency of IndexBuilder cannot be found on the classpath
That is, when loading the class, it's possible (even likely) that the class can be found but that some critical dependency of the class cannot be found. For example, if IndexBuilder extends another class and that base class cannot be found on the classpath, you'll get this error. Another example is if IndexBuilder uses a class in a static initializer and that class cannot be found.
Check your classpath not just for IndexBuilder but also for anything that IndexBuilder depends on.
See, for example, this discussion of NoClassDefFoundError.
When you are running it from the command line, you are actually invoking Apache Ant. The reason you are getting the ClassNotFound Exception is because ${javac.classpath} and all the other properties are not being properly populated. That is why your code runs from within the Netbeans context. Netbeans is setting those properties for you.
To answer your original question of how do you go about getting it to run from the command line, you need to either set up a properties file that defines those parameters via a property declaration:
<property file="myproject.properties"/>
Another solution is to set the properties as environment variables via a sh script. Or you can use real paths in the build script instead of properties.
See here for more details on how to invoke Ant from the command line.
Did you try setting the working directory to "build\classes" in the Project Properties -> Run tab?
At least one of the JARs/Libs referenced by your project may not be being copied to the class path of your program. Copy all of the jars/libs that your project uses to the /dist folder of your project (or wherever YourApplication.jar is), then try to run your program. If this fixes it it means your Netbeans project isn't configured quite correctly.
Are you running this on Windows or Unix. If Windows, try changing your property file to:
run.classpath=${javac.classpath};${build.classes.dir}
Please note the semicolon instead of a colon.

Categories