Multiple jars in classpath not working - java

I have seen several very similar questions on stackoverflow, but haven't come across anything that exactly matches my problem. I have a folder with several .java files, and another folder with two .jar files. I need to include both the jar files while using javac so that the entire project gets compiled at one go:
$: javac -classpath .:~/myjardir/*.jar ~/myprojectdir/*.java
But if I do this, only the first jar is recognized, and everything that depends on the second jar throws an error. Surprisingly, if I compile each program separately,
$: javac -classpath .:~/myjardir/oneofthejars.jar ~/myprojectdir/file1.java
then everything works fine. I have also compiled the project separately in Eclipse just to test the code and the jars. It is only when I try to use both the jars with -classpath in command line that I get the errors. Wildcard entries are supposed to work in JDK6, so I am at a loss here.

The class path wildcards don't work like they do in the Unix shells. The * means everything named *.jar in the directory. So you don't need to do *.jar but just *. The following should do what you want:
$: javac -classpath .:~/myjardir/* ~/myprojectdir/*.java
See Understanding class path wildcards in the Java SE 6 documentation.

see the SO answer here but here's the relevant paragraph from the Java documentation:
Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. For example, the class path entry foo/** specifies all JAR files in the directory named foo. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory.

if you want multiple things in a classpath, you have to separate them by the classpath separator as far as I know. So ./lib:/lib/mylib would be a valid classpath on a unix system, I think the equivalent would be .\lib;\lib\mylib on a windows system. You don't have to specify every file, just the directories.

Related

Override ClassPath in Bash script to run Java application

I am trying to run a simple Java application in Unix. My Java application read a config file from a directory at run-time. I placed the files in /tmp/paddy/. I created a simple bash script to run a application.
I tried like below and it gives me "no main manifest attribute, in app.jar" error
#!/bin/bash
java -cp ".:./config/*.*" -jar "app.jar" com.test.MainClass
And tried with below command This time my application is running but couldnt find the aconfig file so it throw me NullPointerException - (since it couldnt load the config file)
#!/bin/bash
java -cp app.jar com.test.MainClass
What is the correct way to override classpath in Java -cp command ? I was searching over the internet, but couldnt get any good answers. I dont have any issues running in windows. Only in linux and I am pretty new to the linux environment.
You have four separate issues here.
-jar and -cp don't work together
If you use the -jar switch, the classpath is taken from the Class-Path manifest entry in the jar's manifest, and that is all that will happen - the -cp switch (and the CLASSPATH environment variable) are completely ignored. The solution is to fix your jarfile, which ought to have that classpath entry.
That's not how bash works.
Separate from that issue, your -cp parameter is broken.
*.* in.. linux...? That's late 90s DOS, mate!
It's java doing the parsing of that *, which is unique, because in linux it's normally bash doing it, but that doesn't work here, because bash will be adding spaces, and java needs colons/semicolons, which is why java does it itself. The point is, java is rather limited and only understands a single *. Which bash will mess up. So, there is really only one way to do this.
Single quotes.
One star.
For example:
java -cp '.:./config/*' com.test.MainClass
You don't seem to understand how classpaths work
Each individual entry in a classpath must be either:
A directory which contains classfiles.
A jar file
Note how it specifically cannot be 'a directory that contains jar files', and also cannot be 'a class file'; that is not a thing. The * is the usual treatment: It takes every file in the directory you padded with /* and considers them all to be part of the classpath.
So, if you write: java -cp ., that will not include app.jar. If you write java -cp './config/*', that will not include any class or config files hanging off of ./config (only jar files located there).
That's not how config files work
Including config files on the classpath is not how its done. You can, of course. This doesn't do anything whatsoever, unless you are using SomeClass.class.getResource or some other variant of getResource (those are no good, you should be using SomeClass.class.getResource or SomeClass.class.getResourceAsStream, but I digress), in which case, don't do that. Those aren't intended for config files, those are for static files (files that never change, such as, say, a 'save to cloud' icon for your swing user interface application). If you are doing that, you'd need to include ./config (and not './config/*') in your classpath, but it would be a better idea to fix your code.
config files should be in the user's home directory - System.getProperty("user.home"). You should consider the directory that contains the jar file(s) as the place where the executables live, and those are not necessarily editable by the user, and surely the point of a config file is that you can edit them. Hence why using the classpath for these is not how it is done.

Cannon Find Symbols Error

So I'm trying to run
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_73
javac com/darkblade12/enchantplus/*.java
jar cvf program.jar -C com/darkblade12/enchantplus
in command prompt as I'm not fluent in any language or Eclipse, but I get a cannot find symbols error for many of the items "compiled", I originally just tried to recompile a .jar in Java7 rather than Java8 because I had the source code and needed it in the format for Java7, so any help with either would be great.
Your question is not very clear, but, I guess you only want to compile your classes.
The value of JAVA_HOME variable has blanks in it. You might want to put it in quotes or use the windows shortened path names, like shown here How can I find the short path of a Windows directory/file?.
You are missing a source file, or possibly an external library your program depends on. If you find Configuration.java, you can add it to your enchantplus folder, maker sure to give it the same package name as the one in IndependantConfigurationSection.java and it should compile. If it is a .class file packaged in a .jar file,you need to add that jar to your classpath using
javac -cp {path-to-class-or-jar} com/darkblade12/enchantplus/*.java

Setting Classpath but Java program(using Apache external jar) doesnt run on CMD Line

So I followed a couple of tutorials and I am basically trying to run a java program on cmd line with an External Jar. I know that there are plenty of questions about this, BUT after trying the code suggested I get two errors.\
Its a simple program called "HelloJar.java" and it utilized Apache Commons Lang String Utils.
Error I see (As you can see I set the classpath and run it.):
Works fine in Eclipse though:
Folder Structure (In jars is the jar necessary and in Src is the project I need):
Here is the .jar file that I import for StringUtils:
What does the cannot find symbol mean?
-----------------------After Rajesh's Answer------------------------------------
Problem here is, jar's not set in classpath and results in compilation errors:
As per path shared, command to compile should be :
cd C:\Users\Controlled\Documents\Eclipse_Projects\HelloWorld\src
javac -cp .;C:\Users\Controlled\Documents\Eclipse_Projects\HelloWorld\jars\* HelloJar.java
Command to run java program with above path:
java -cp .;C:\Users\Controlled\Documents\Eclipse_Projects\HelloWorld\jars\* HelloJar
What does the cannot find symbol mean?
That means, compiler is unable to find the specified path in the classpath. So, that means, when you are trying to run your jar from command line, your library which has
org.apache.commons.lang.StringUtils
is not found. So, in order to fix that, please check if the library is included in your jar or if you have that in classpath and specifying the correct classpath.
Although you did set your classpath to the correct folder, windows fle path separation is different from a Unix Box.
javac -cp ".;./jars/org.apache.commons.lang.StringUtils.jar/" HelloJar.java
java -cp ".;./jars/org.apache.commons.lang.StringUtils.jar/" HelloJar
Another Java distinction is that the classpath is the compile-time path. It is not the same as the execution-time path.

java.class.path doesn't bring Manifest.mf Class-Path property

I'm trying to get my application classpath.
I have a jar (named application.jar) and it have in its Manifest.mf other jar files, like Class-Path: a.jar b.jar.
Why when I use System.getProperty("java.class.path") my jars a.jar and b.jar are not listed?
It possibly has to do with the fact that the java.class.path is a system property that is set from the classpath environment variable ($CLASSPATH or -classpath). These are ignored with the -jar option is used.
As per the java -jar documentation, when that jar option is used to run an application, only the manifest Class-Path is considered and other settings are ignored.
From http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/java.html:
-jar
Execute a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. Here, classname identifies the class having the public static void main(String[] args) method that serves as your application's starting point. See the Jar tool reference page and the Jar trail of the Java Tutorial for information about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
That's excactly the question I came along as well. Even if when using java -cp ..;myTest.jar test2.Needer I get only "..;myTest.jar" as a result for java.class.path property.
Note: Even when using the -cp parameter the given class-path in the MANIFEST.MF is searched! (Couldn't find this information on google and tested myself)
So i don't think that is has something to do with the -jar parameter. In Link you can find
Expansion of wildcards is done early, prior to the invocation of a program's main method, rather than late, during the class-loading process itself.
Interestingly i found out during my tests: The classpath in MANFIFEST.MF is searched recursivly. So if there is an given test.jar File in the classpath in MANIFEST.MF of myTest.jar, the class-path in the MANIFEST.MF of the test.jar will be looked up as well (when using java -cp "myTest.jar" test2.Needer).
As a result, when the java.class.path property would support showing the the classpath of the MANIFEST.MF, it should also show the classpathes of all subsequently depending .jar files. Since the classpath is only searched until classes are found, this wouldn t refer nicely to the lazy loading mechanism.
TL;DR: I think that this has nothing to do with the -jar Parameter (-cp is concerned as well). In my explanation, the support for showing the classpath from the MANIFEST.MF would only come with additional, senseless recursive search costs (because there needn't to be an actual dependency, respectivly what is used from the .jar). And since this sensless search would delay the program start (since the recursive search could be really deep), it is not implemented.

Setting the classpath for JAR files

I have recently just created Java project using Eclipse that requires 2 JAR files (phiget21.jar and the mysql.jar)
Everything works fine when running the programme in Eclipse, and I have noticed the the jar files are saved in a 'lib' folder.
I soon going to me moving the programme off my computer to be used on other machines, so I decided to create a batch file to compile all of the classes and then run.
However, I am having trouble with the locating of the jar files. In the batch file do I require a command something like: set classpath=.:..;mysql.jar:../phidget21.jar, before the compilation of the Java classes?
I have read that the dots (...) have something to do with directories but not entirely sure how to implement them.
My programme is currently saved in these locations:
Project/src/.java files (I have also put the .jar files in here as well as i thought this may make thing s easier)
Project/lib/ .jar files
Any help would be greatly appreciated!
while setting the classpath a single dot (.) means current directory. As you jar files are in current directory, you just need to go to your current directory using cd command in DOS prompt, then use
set classpath = .;filename.jar;another filename.jar
Here . represents current directory and semicolon separates each classpaths.
You can even set classpath of more than one jar files using wild card character * which can be read as all.
You need something like
java -classpath lib/foo.jar:. com.company.Program
you can also use wildcards since java 6. see here
so the above becomes
java -classpath lib/*:. com.company.Program

Categories

Resources