I have this Java code:
public class Calc {
public int quotient(int a, int b){
return a/b;
}
}
and TestNG unit test for this method:
#Test ()
public void testingMethod3() {
Assert.assertEquals(0, calc.quotient(5,0));
}
On my work computer I successfully get
java.lang.ArithmeticException: / by zero
message, as expected.
But when my colleague runs this test on home computer, then mentioned exception is not throwing and test passes.
How this magic could occur?
P.S.
Environment
OS: Windows 10
TestNG version: 6.13.1
Java version: 8 (don't know exact build version)
P.P.S.
Deletion of target folder and rebuilding of the project was that very helpful solution. Seem like IDE cashed old project sources, and didn't flush them after changes in the code.
In the past, I experienced something like yours. Because different JDK compile environment and/or JRE runtime environment. And need check the different of version of TestNG.
check by add few line of code to print Java properties.
Properties p = System.getProperties();
Enumeration keys = p.keys();
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
String value = (String)p.get(key);
System.out.println(key + ": " + value);
}
then comparing
Related
Let's say i have a code like this :
public class Test {
public static void main(String args[])
{
int x = 5;
// Widening Casting
double myNum = x;
System.out.println(x + " " + myNum);
}
}
Now i write the following commands in powershell changing the value of x from 5 to 6 once in my code and saving it, it works perfectly fine. But tutorials online suggest me to use javac for compilation. Why so?
From Java 11 onwards, the java command is able to compile and run a single Java source file with a static void main(String[]) entry point method. (This feature was added as JEP 330.)
The online tutorials are correct for Java 10 and earlier, and they are correct for cases where more than one Java source file needs to be compiled.
I am setting up a java framework that should use the Google OR-Tools. The code below compiles successfully, but throws an exception at runtime:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.google.ortools.linearsolver.operations_research_linear_solverJNI.MPSolver_CLP_LINEAR_PROGRAMMING_get()I
at com.google.ortools.linearsolver.operations_research_linear_solverJNI.MPSolver_CLP_LINEAR_PROGRAMMING_get(Native Method)
at com.google.ortools.linearsolver.MPSolver$OptimizationProblemType.<clinit>(MPSolver.java:221)
at Main.main(Main.java:15)
I am using Intellij 2018.3 on Windows 10. I spent a lot of time trying to get this run, but unsuccessful. Based on what I found on the internet, the exception might be caused by poor linking and/or missing external libraries on which OR-Tools depends. However, I don't have the background to resolve this issue, and also Intellij does not highlight anything. Any idea what the problem is?
For completion, this is the code I run:
import com.google.ortools.linearsolver.MPObjective;
import com.google.ortools.linearsolver.MPSolver;
import com.google.ortools.linearsolver.MPVariable;
public final class Main {
public static void main(String[] args) {
// Create the linear solver with the GLOP backend.
MPSolver solver =
new MPSolver("SimpleLpProgram", MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
// Create the variables x and y.
MPVariable x = solver.makeNumVar(0.0, 1.0, "x");
MPVariable y = solver.makeNumVar(0.0, 2.0, "y");
System.out.println("Number of variables = " + solver.numVariables());
// Create a linear constraint, 0 <= x + y <= 2.
MPConstraint ct = solver.makeConstraint(0.0, 2.0, "ct");
ct.setCoefficient(x, 1);
ct.setCoefficient(y, 1);
System.out.println("Number of constraints = " + solver.numConstraints());
// Create the objective function, 3 * x + y.
MPObjective objective = solver.objective();
objective.setCoefficient(x, 3);
objective.setCoefficient(y, 1);
objective.setMaximization();
solver.solve();
System.out.println("Solution:");
System.out.println("Objective value = " + objective.value());
System.out.println("x = " + x.solutionValue());
System.out.println("y = " + y.solutionValue());
}
}
In my case solution was simple - I just needed to add this singe line of code:
Loader.loadNativeLibraries();
where loader comes from com.google.ortools.Loader
Disclaimer: more a long comment than an answer...
note: I supposed you are using the github repository of or-tools if you used the binary package it should be more or less the same...
1) You must load the jni library which will load the OR-Tools C++ libraries and its dependencies...
/** Simple linear programming example.*/
public class Main {
static {
System.loadLibrary("jniortools");
}
public static void main(String[] args) throws Exception {
2) Did you manage to run the java samples ?
make run SOURCE=ortools/linear_solver/samples/SimpleLpProgram.java
ref: https://developers.google.com/optimization/introduction/java#simple_example
3) As Kayaman pointed out, you must pass the folder where the java runtime can find the native libraries (i.e. the JNI wrapper jniortools.dll and its dependencies libortools.dll)
if you look at the console log you'll see the full command line:
java -Xss2048k -Djava.library.path=lib -cp lib\sample.jar;lib\com.google.ortools.jar;lib\protobuf.jar ...\sample
Which comes from, the makefiles/Makefile.java file:
JAVAFLAGS = -Djava.library.path=$(LIB_DIR)
...
ifeq ($(SOURCE_SUFFIX),.java) # Those rules will be used if SOURCE contain a .java file
$(CLASS_DIR)/$(SOURCE_NAME): $(SOURCE) $(JAVA_OR_TOOLS_LIBS) | $(CLASS_DIR)
-$(DELREC) $(CLASS_DIR)$S$(SOURCE_NAME)
-$(MKDIR_P) $(CLASS_DIR)$S$(SOURCE_NAME)
"$(JAVAC_BIN)" -d $(CLASS_DIR)$S$(SOURCE_NAME) \
-cp $(LIB_DIR)$Scom.google.ortools.jar$(CPSEP)$(LIB_DIR)$Sprotobuf.jar \
$(SOURCE_PATH)
...
.PHONY: run # Run a Java program.
run: build
"$(JAVA_BIN)" -Xss2048k $(JAVAFLAGS) \
-cp $(LIB_DIR)$S$(SOURCE_NAME)$J$(CPSEP)$(LIB_DIR)$Scom.google.ortools.jar$(CPSEP)$(LIB_DIR)$Sprotobuf.jar \
$(SOURCE_NAME) $(ARGS)
endif
src: https://github.com/google/or-tools/blob/46173008fdb15dae1dca0e8fa42a21ed6190b6e4/makefiles/Makefile.java.mk#L15
and
https://github.com/google/or-tools/blob/46173008fdb15dae1dca0e8fa42a21ed6190b6e4/makefiles/Makefile.java.mk#L328-L333
note: you can run make detect_java to know the flags i.e. value of LIB_DIR
note: if you did use the precompiled package the Makefile is here:
https://github.com/google/or-tools/blob/stable/tools/Makefile.cc.java.dotnet
Then after you can try to add this option in Intellij...
You must understand that or-tools is a set of C++ native libraries which are wrapped to Java using the SWIG generator.
To make it work using Intellij (over a windows machine) you need to:
Install Microsoft Visual C++ Redistributable for Visual Studio
Download and extract the OR-Tools library for Java
In intellij, add jar dependency to the 2 jars under the lib folder of the extracted files (each of the 2 jars separately, do not add to lib folder itself. This is why).
Add the lib library path to VM options. In Intellij edit your run-configuration and add to vm options: -Djava.library.path=<path to the lib folder that hold the jars>
Load the jni library statically by adding the below code to your class (as mentioned here.)
static {
System.loadLibrary("jniortools");
}
The below code gets compiled successfully, wherein inside some class, I have written two methods with same name & same type signature. Am using Eclipse Oxygen 4.7.0 and I can see error Duplicate method show(int,int) shown in red. But when I compile the code, its getting compiled successfully with correct output. When I run the same code in command prompt using javac its validly not getting compiled.
package oops2;
class A6
{
int i, j;
void show(int i, int j)
{
System.out.println(" i & j : " +i + " " +j);
}
void show(int k, int l)
{
System.out.println("override or not");
}
void show(String s)
{
System.out.println("Entered str is "+s);
}
}
public class OverrideNoInherit
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
A6 a = new A6();
a.show(20, 30);
a.show("this is it");
}
}
Here, I want to mention that when I click on run on Eclipse, I get a pop-up saying
Errors exist in this project, proceed with launch?
Now, didn't this error mean that there are other classes in same project which had errors & thus did not get compile. I don't think this meant that despite there being errors in code, the programs would get compiled. Then what would be difference between warnings & errors?
Eclipse always compiles classes. The body of methods containing errors are replaced by a method that throws a java.lang.Error containing the compile errors of that class. This is actually helpful for test driven development that allows you to start tests on classes that have compile errors. The methods that are compilable can be tested even if some other parts are currently containing errors.
You've got a special case here. The compiler is able to compile the first occurance of the method but later comes across the duplicate method that can't be added to the class. Because the first method is already compiled and when you enforce the starting of the class despite the warning you see the regular method that was successfully compiled in action.
I try to retrieve the windows directory of my OS.
To get the correct path I tried the following 2 commands:
System.getenv().get("WINDIR")
System.getenv().get("SystemRoot")
Both commands work, but the strange thing is, that the first command (WINDIR) returns the path only, if I
run the program in debug mode. The latter command (SystemRoot) returns the path only if I run the program not in debug mode.
So this program
public static void main(String[] args) {
System.out.println(System.getenv().get("WINDIR"));
System.out.println(System.getenv().get("SystemRoot"));
}
evaluates to
// Debug mode
C:\Windows
null
// No Debug mode
null
C:\Windows
Is this a defined behavior?
(My application is Windows specific, and if i speak of debug mode I mean the default Eclipse "Debug as Java Applicaton" run configiguration)
System.getEnv() is an overloaded method, one implementation having no parameters and one having a String parameter.
static Map getenv​() Returns an unmodifiable string map view of the current system environment.
static String getenv​(String name) Gets the value of the specified environment variable.
You are calling the implementatation with no parameters, and then calling get() on the returned Map. From the Javadoc for System.getEnv():
For getEnv(): The returned map is typically case-sensitive on all platforms.
For getEnv(String): On UNIX systems the alphabetic case of name is typically significant, while on Microsoft Windows systems it is typically not.
So it is essential for your code to be providing the name of the environment variable in the correct case, specifying windir in all lower case, not upper case.
That said, I can't explain the differences you see when running in debug mode at all. If I run the program below - which is just an enhanced version of yours - I get identical results (as expected) regardless of whether it is run in debug mode or not:
System.getenv().get() windir=C:\WINDOWS
System.getenv().get() WINDIR=null
System.getenv().get() systemroot=null
System.getenv().get() SystemRoot=C:\WINDOWS
System.getenv() windir=C:\WINDOWS
System.getenv() WINDIR=C:\WINDOWS
System.getenv() systemroot=C:\WINDOWS
System.getenv() SystemRoot=C:\WINDOWS
Could you run the code below twice, once in debug mode and once in normal mode, and advise of the results? Also, advise of your environment: Windows version, Eclipse version and Java version.
[This is more of a request for further information than a final answer, but I couldn't fit it all into a comment.]
import java.lang.management.ManagementFactory;
import java.util.regex.Pattern;
public class App {
private final static Pattern debugPattern = Pattern.compile("-Xdebug|jdwp");
public static boolean isDebugging() {
// https://stackoverflow.com/questions/7397584/how-to-know-my-code-is-running-in-debug-mode-in-ide
// Taken from the code provided by SO user AlexR
for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
if (debugPattern.matcher(arg).find()) {
return true;
}
}
return false;
}
public static void main(String[] args) {
System.out.println("Running in debug mode? " + App.isDebugging());
System.out.println("System.getenv().get() windir=" + System.getenv().get("windir"));
System.out.println("System.getenv().get() WINDIR=" + System.getenv().get("WINDIR"));
System.out.println("System.getenv().get() systemroot=" + System.getenv().get("systemroot"));
System.out.println("System.getenv().get() SystemRoot=" + System.getenv().get("SystemRoot"));
System.out.println("System.getenv() windir=" + System.getenv("windir"));
System.out.println("System.getenv() WINDIR=" + System.getenv("WINDIR"));
System.out.println("System.getenv() systemroot=" + System.getenv("systemroot"));
System.out.println("System.getenv() SystemRoot=" + System.getenv("SystemRoot"));
}
}
Recently had a problem with
java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available
Tried to isolate the problem, using this simple code:
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
public class Main {
public static void main(String... args) {
final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
Mac instance;
try {
instance = Mac.getInstance(HMAC_SHA1_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
final String errmsg = "NoSuchAlgorithmException: "
+ HMAC_SHA1_ALGORITHM + " " + e;
// ...
}
}
}
The thing is that this works in one of my Eclipse instances, and not on the other. All tested using New Java Project, pasting the above, and running, so this should be due to some settings difference between the Eclipse instances.
I've tried to look through all the seemingly relevant settings (classpath, JRE, java compiler), but nothing that looks different or makes it work if changed. (If someone knows how to 'diff' the settings of two Eclipses, do tell!)
I'm resorting to simply using a third Eclipse (where it works (so far)), but it would still be interesting to learn what this potentially infuriating problem is really down to.
I had that same Exception using Eclipse and tomcat, what I did was :
Reload JDK over TOMCAT 8 configuration, and it started working