I noticed that when running a Java application or unit test in Eclipse, it explicitly adds the jars of the JRE (rt.jar, etc.) to the -classpath argument of java.
First question: Why? This seems unnecessary, since those jars are implicitly on the bootstrap classpath anyway, right?
Second question: Is there a way to prevent Eclipse from doing that? I found that I can remove those jars from -classpath by deleting the "JRE System Library" from the "Bootstrap Entries" in the Classpath tab for a specific run configuration, but I would like to configure this for the whole project, no for every run config separately.
Related
I have a project 1 which need to run on 1.7, this project has a dependency on another project 2 built on 1.8.
I am trying to invoke a class from Project 2 inside Project 1, but I am getting a known error which is fixed in 1.8. I f I run this class individually on Project 2 in JRE 1.8, it works fine.
Any leads to chose the target JRE dynamically for a method call?
If you are willing to make a jar and use a wrapper for each program, you can bundle a specific jre with each executable.
Download and run Launch4j
In your eclipse project, click on:
File -> export -> runnable jar file -> next
And select the run configuration for the project you'd like to extract. Hit Finish
It's a good idea to test each jar and make sure it runs. Double click, or find it with cmd and do java -jar nameOfJarToTest.jar.
Make a subfolder for your jre. I just called mine "jre".
Copy and paste your bin and lib folders from the correct jre into that folder you just made. Mine are located in a place like C:\Program Files\Java\jre1.8.0_201 if you wanted to run java 8. To be extra clear, your file structure should be
someContainerFolder(folder you just made)
nameOfJarToTest.jar
jre(folder you just made)
bin(folder copied from the jre in your file system)
lib(folder copied from the jre in your file system)
Run Launch4j. Add the .jar and select an output file path. Fields pictured below
Click on the jre tab and add your respective jre in the min jre field. Make sure you select the option Only use private jdk runtimes. Type "jre"(if you named the folder with 'bin' and 'lib' jre) in the "bundled jre path" field pictured below.
Click on 'build wrapper'. It looks like a settings cog.
If you do this for both jar files, and make sure the 'bin' and 'lib' folders are from the jre you want to run, the two programs will both run fine in different runtime environments. If you would like one program to be able to call the other, I found the geeksforgeeks website has a very simple and concise way for you to call external executable files from your code if you're okay with canonical paths.
This is not possible, if your project depends on 1.7 it's dependencies should also be 1.7. At runtime all code executes in the same JVM, there is no way to dynamically 'choose' a target JRE.
If you really have no other option and the two libraries should work together, you could possibly build some kind of bridge between project 1 and 2, where project 1 invokes project 2 in a separate JVM instance.
Here are some questions about setting the CLASSPATH in IntelliJ:
Adding Jar files to IntellijIdea classpath
how to add directory to classpath in an application run profile in intellij idea?
Java - setting classpath
Most of the answers involve changing settings in the Project Settings -> Modules -> Sources or -> Dependencies pages. But the word "CLASSPATH" isn't actually on those pages.
For example, the -> Dependencies page lets one explicitly set a place to find other .class files or .jar files. But no "CLASSPATH" anywhere.
Also, setting a location in the -> Sources page seems to indicate what the directory tree for
the .class root should look like, but the actual location is actually set in the Project Settings -> Project -> Project Compiler Output field, again without the word "CLASSPATH".
Is JetBrains trying to hide this word for some reason (eg. it's meant to be a multi-language IDE)? Is there some place to explicitly set the CLASSPATH other than an env variable?
As you say, the CLASSPATH is an environment variable, so it would affect all applications referencing that variable:
The class search path (more commonly known by the shorter name, "class
path") can be set using either the -classpath option when calling a
JDK tool (the preferred method) or by setting the CLASSPATH
environment variable. The -classpath option is preferred because you
can set it individually for each application without affecting other
applications and without other applications modifying its value.
Source: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
You can also use the -classpath option when running your application, which would not affect other Java applications running on your system.
IntelliJ will construct your classpath to include both your application and any dependencies (whether folders or Jars etc.) and passes that to the JVM when you run your application. The IntelliJ GUI does refer to your explicit "Dependencies" and let you edit them. Your application build path would need to contain those dependencies and all of your application code, so it makes sense to include that implicitly.
If you were to use a lot of libraries, your classpath could become very long - having to maintain the list of locations in the class search path manually would be time consuming and (human) error prone - a typo on a folder name and it won't compile / run - so it assumes the task for you.
You'll probably find your IDE passes a number of other arguments to the JVM on your behalf (heap size, GC, JMX extensions and so on) - but that's part of what your IDE is for. Sure, we could invoke things like version control ourselves from the command-line, but why forgo the help? Your IDE isn't trying to "hide" anything from you, it's (hopefully) providing a more intuitive interface for many common development tasks.
CLASSPATH happens to be the name of the environment variable used automatically by Java.
It's generally considered a better option to use the -cp argument to explicitly set the classpath rather than fighting with CLASSPATH conflicts since it's process-wide.
It's not trying to "hide" it at all; there's just no reason to use it.
I would like to use the library "Lucene" with java. The instructions to use it tell me I have to put the jar's cointaining the classes inside the CLASSPATH.
The CLASSPATH is the directory containing all the default classes of Java? Or the directory of my specific project? I'm using Eclipse as IDE.
Really confused about that! Thank you.
USEFUL SOLUTION: http://www.avajava.com/tutorials/lessons/how-do-i-use-lucene-to-index-and-search-text-files.html
The Classpath is a collection of directories and JAR files inside which the Java runtime will look for classes.
It can be configured via an environment variable named CLASSPATH, but this usage is not recommended, as it tends to constantly result in problems.
The preferred way to configure the classpath when running a Java program is to pass it via the -cp command line switch when you start the Java interpreter. Usually you write a shell script so you don't have to type it out every time.
If your issue is with using the classes inside the IDE where you write your code, then it depends of course on the IDE. For eclipse, the "Java Build Path" tab of the project properties is where you configure the classpath.
I am using DeferredTextImpl Class and eclipse does not seems to complain about it but when I run my project I get run time exception .... Class not found exception for DeferredTextImpl ..
When I searched for the class file, I found it in rt.jar which should certainly be on the class path. I also checked the build path in project properties->Java build path and could see JRE System Library at the very bottom. when I expanded that. I could see rt.jar. which means it is on the class path, right ?
Why am I getting this error ?
There is a difference between the build path in Eclipse and the classpath when you run your code. The build path is used to compile your code. The classpath is what your application has when it runs.
The build path is configured with Project -> Properties -> Java Build Path
The class path is configured with Run -> Run Configurations -> Classpath
In your case, you should also check (as others mentioned), if the JRE tab under Run Configurations points to the same JRE as in your build path.
Check the version of your Xerces jar for your runtime versus you compile time classes. Make sure have a Xerces2 jar at runtime. I doubt the the class in the rt.jar is the same class your application is looking for.
This class is part of a specific DOM implementation (Apache Xerces). It's not part of the public Java API, and if you do in fact find it in one JVM's runtime class library, this is no guarantee it'll be in others. If you need to explicitly work with Xerces, then you need to explicitly include the Xerces libraries on your runtime class path.
Can you try running the code by explicitly adding rt.jar with -jar option while running the code? If this works then it means that the rt.jar in eclipse is not on classpath.
Right click on project > java build path > Libraries
remove JRE and add library pointing to JDK folder which in my case is C:\Program Files\Java\jdk1.7.0_55.
But before that do the same thing with java installed JRE as well.
Windows > java > installed JRE .
Hope this will help
I've built a JAR file and it executes fine on my PC (XP) which has Eclipse installed. It also works on another PC, which also has Eclipse.
I've tried running it on another PC(XP) that does not have Eclipse. Though it contains the JDK and multiple JRE. The JAR file just does not execute by clicking or from the command prompt.
I am not entirely sure, but my best guess is the Environment Variables are not set properly. Here is the error I receive from the command prompt:
Exception in thread "main" java.lang.NoClassDefFoundError: ...
Any help would be appreciated.
It must be a CLASSPATH issue.
The stacktrace should also say which class it failed to find. Once you have that, then find which jar has that class. Then add that jar file to your classpath or add it to the classpath env variable.
This is likely a classpath issue as others have said.
One thing to note is how your jar is constructed. You have a number of options in the dialog for exporting a runnable jar;
Extract classes into jar
Zip dependencies into the jar - creates jar-in-jar-loader.jar inside the jar.
Place jars in a subdirectory next to the jar.
Depending on what you have chosen for this depends on how the jar will behave. If the classes are extracted, dependent classes not in the JDK should be on the classpath. I'd recommend this course of action as it is simpler.
Now, the question is - are you using a dependency on your classpath not in the build dependencies of the eclipse project? If so, it won't be packed with / zipped into / put next to the jar because eclipse doesn't know about it (but java will still find it on your system because it's on the classpath). Also, if you've saved an ANT script and updated the build path in eclipse, eclipse won't update that ANT script - that is generated once only.
Environment variables are not considered when invoking a jar file when clicking on it (equivalent to running javaw -jar your.jar).
I'm pretty sure that it doesn't work on your first PC outside of Eclipse either.