I need help getting a file from a file to use it.
The file is specified in the -cp option when running jar through the console.
run the jar using:
java -cp myjar.jar:dir1/dir2/myfile.txt com.company.Main
execution result:
Exception in thread "main" java.lang.NullPointerException
at com.company.Main.main(Main.java:11)
source code:
package com.company;
import java.io.InputStream;
public class Main {
public static void main(String[] args) {
ClassLoader classLoader = Main.class.getClassLoader();
InputStream resource = classLoader.getResourceAsStream("dir1/dir2/myfile.txt");
System.out.println(resource.toString());
}
}
project tree
-- сom
---- company
------ Main.java
How do I get that file from -cp?
Since you specify dir1/dir2/myfile.txt in the getResourceAsStream() call, you want the directory containing dir1 on the classpath, which would be the working directory, i.e. .:
java -cp myjar.jar:. com.company.Main
The classpath can only specify:
Directories
Jar files
No other type of file is supported.
It appears that your computer cannot find the file. Right click on the file and select explorer to see the path or if you are using intellij idea you will see an option to copy the path when you right click on it.
Related
I'm trying to run a java file which is in the /lib/jarfile.jar jar file in the path "il/co/codeguru/corewars8086/CoreWarsEngine" with this command in linux:
java -cp lib/jarfile.jar il.co.codeguru.corewars8086.CoreWarsEngine
but I get this error message:
Error: Could not find or load main class il.co.codeguru.corewars8086.CoreWarsEngine
I read I little bit about classpathes in java but i still don't know what is wrong with what I did...
this is the content of CoreWarsEngine
package il.co.codeguru.corewars8086;
import il.co.codeguru.corewars8086.gui.CompetitionWindow;
import java.io.IOException;
public class CoreWarsEngine
{
public static void main (String args[]) throws IOException
{
CompetitionWindow c = new CompetitionWindow();
c.setVisible(true);
c.pack();
}
}
Make sure the jar file exists at the location you expect it to be and matches the jar file name in the command. This may seam silly, but java that I have, 11 AdoptOpenJDK does not complain that it did not find the jar file:
java -cp nonexistingfile.jar il.co.codeguru.corewars8086.CoreWarsEngine
Error: Could not find or load main class il.co.codeguru.corewars8086.CoreWarsEngine
Caused by: java.lang.ClassNotFoundException: il.co.codeguru.corewars8086.CoreWarsEngine
Second make sure the jar contains the class you are trying to start. I have stumbled on at least one corewars8086 download on the net that does not have the CoreWarsEngine class.
If you got the sources from GitHub/codeguru-il/corewars8086 then you need maven to build it. The resulting jar will be in target/corewars8086-4.0.0-SNAPSHOT-jar-with-dependencies.jar. Or if you build it a different way then you need to figure out where the result jar will be and what is the name.
I managed to run it from the sources of the above repo
I'm trying to create a jar file and run it using java -cp main.jar com.test.Foo.Main but I keep getting:
Error: Could not find or load main class com.test.Foo.Main
Caused by: java.lang.ClassNotFoundException: com.test.Foo.Main
This is my file structure. So I'm thinking the line in my Main.java should be package com.test.Foo correct?
I'm compiling my Main.java with javac Main.java which outputs a Main.class file. Afterward, I create a jar file using jar cfm main.jar META-INF/MANIFEST.MF Main.class and finally while I'm in the same directory as the jar file <root>/src/com/test/Foo/ I run java -cp main.jar com.test.Foo.Main and that's when I run into the above error. Any idea how I can run this file like this (and yes I need it to run with this command specifically)?
Main.java
package com.test.Foo;
public class Main {
public static void main (String args[]) {
System.out.println("I am com.test.Foo.Main");
}
}
META-INF/MANIFEST.MF
Manifest-Version: 1.0
Main-Class: com.test.Foo.Main
I tried using some of the options given in this popular SO question and nothing helped.
The picture you're showing in your question is your project structure not your jar structure.
When you create a jar file, the structure for that jar file might be
different with your source code folder structure.
Every IDE (such as eclipse, netbeans, IntelliJ) has a mechanism for creating JAR files. In your case when you open the created jar file (using zip apps like winrar) you should see something like this :
com
|
test
|
Foo
|
Main
META-INF
|
MANIFEST.MF
This should be the ordering of your files and folders, otherwise Java can not find your main class from MANIFEST.MF
Now to solve this problem:
Open your jar file using a zip application like winrar
check the folder structure residing inside your jar file as I draw
Fix it right away within the winrar or try to correct your project structure to produce the structure I mentioned.
The class is called com.test.Foo.Main you need to specify the full name in the command:
java -cp main.jar com.test.Foo.Main
or you can use the simpler
java -jar main.jar
Check your META-INF/MANIFEST.MF for the attribute of Manifest-Version: 1.0
This attribute must be there.
Edit:
You need to move to the source root src/ and issue below command to create a valid jar.
javac com/test/Foo/*.java
and, create the jar using,
jar cmf com/test/Foo/MANIFEST.MF main.jar com/test/Foo/*.class
The thing is, package structure should match with the folder structure apparently.
I have the following Java file(apples.java):
public class apples
{
public static void main(String[] args)
{
System.out.println("Apples here.");
}
}
saved in the source folder of the MyProject directory.
I compile apples.java and save the apples.class file into the classes folder of the MyProject directory.
I then create manifest.txt with the following content:
Main-Class: apples
I then navigate into the MyProject/classes directory via cmd prompt(Windows XP) and type the following command:
jar -cvmf manifest.txt app1.jar apples.class
I get the following message in the command prompt:
java.io.FileNotFoundException: manifest.txt (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
What is wrong and how do I fix it?
Put the .jar argument first
jar -cvmf app1.jar manifest.txt apples.class
Make sure both "apples.class" and "manifest.jar" are in the current directory.
I would also encourage you to:
1) Use packages (instead of the default package)
2) Capitalize your class names ("Apples.java" instead of "apples")
Here's a nice, short tutorial that might help:
http://www.mkyong.com/java/how-to-add-your-manifest-into-a-jar-file/
It is a common mistake people make. While creating the manifest.txt, make sure that you don't name it "manifest.txt", after you've already selected the file to be a txt. That makes it "manifest.txt.txt". Hope it helps.
Java and Gradle beginner's question.
I made a project directory for java and gradle test:
The directory hierarchy :
HelloWorld.java:
package foo.bar;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}
build.gradle:
apply plugin:'java'
Then,gradle build this project and generated what i need.
As you see above, my problem is why doesn't this execute correctly? Even through I cd to .class path.
======================================================================
While, if I remove package foo.bar; in HelloWorld.java, and repeat gradle commands and execute at he.bak directory then the error remained the same.
But when I cd to the directory where HelloWorld.java placed. everything goes OK!Why? something related with CLASSPATH environment variables or other causes?
////////////////////////////////////////////////////////////////////
UPDATE
////////////////////////////////////////////////////////////////////
Thought you guys' warm replies, I know that I should combine the CLASSPATH and the period-separated executable .class file to figure out what's going on when executing java class file.
I experiment my thought resulting in 2 point to this question:
The -cp option path parameter A/B plus the executable file c.d.e.class finally form the A/B/c.d.e.class full path where the class is actually located.
If I specify the package in source code file with package d,I must split the full path in the form of java -cp A/B/c/d e.class. split in other ways all will result in errors.
something I am not sure here is :
When I specify my package path in my source code file, It determined the only classpath when executing corresponding executable, right?
If it is the truth, How does a project with lots of package and sources files work?
What's the root principle?
When in build/classes/main try java foo.bar.HelloWorld instead of java HelloWorld
The reason you need to specify foo.bar.HelloWorld is because you specified package foo.bar;. This tells java that the class should be in foo/bar/HelloWorld and the fully qualified name for HelloWorld is foo.bar.HelloWorld. If you want to execute the class from a different working directory however, you can specify the classpath explicitly using the -cp option, e.g., java -cp c:\myproject\build\classes\main foo.bar.HelloWorld.
By the way, the classpath default is the current working directory (i.e., .) but java -cp c:\myproject\build\classes\main foo.bar.HelloWorld will NOT have the classpath set to the current working directory if it is explicitly set using the -cp option. If you want to include the current working directory but explicitly set it, or even add more directories, you can chain them using semicolons like this: java -cp .;c:\myproject\build\classes\main foo.bar.HelloWorld. So this will include both the current working directory and the directory I specified.
I am importing one class(it is not there in the default jvm) from one jar package and using it in another package. like I have a class program1.class in package package1 and I am importing this class from another programme program2 in package package2.
package package1;
public class Program1
{
public String sayHello()
{
return "Hello world";
}
}
and importing this class in
package package2;
import package1.Program1;
public class Program2
{
public static void main(String args[])
{
System.out.println("I am in programme2");
System.out.println("I am in programme 1"+new Program1().sayHello());
}
}
I have compiled the program1 and packaged it by
javac -d . Program1.java
jar cf Pack1.jar package1
and second programme by
javac -d . Program2.java
jar cfm Pack2.jar Manifest.txt package2
my manifest file is
Main-Class: package2.Program2
now I am running the programme as
java -classpath path/to/Pack1.jar -jar Pack2.jar
it is giving me error as:
I am in Program2
No class def found error Package1/Program1
If I am running it by specifying the Class as
java -classpath path/to/Pack1.jar;path/to/Pack2(UnJar'ed) Pack2.program2
it is working which is very strange
Means there is a different between specifying the class file containing the main and specifying the jar file of the program.
I have already made sure that I have set Main-Class is set correctly in Manifest.mf, moreover the classpath for pack2 is also specified
So why this error
When you use the -jar option, all other classpath options are ignored. Thats why you are getting a NoClassDefFoundException.
See link here.
Here is the relevant note from that link --
-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.
The fix would be to include the Class-Path in your jar manifest.