IntelliJ: Why can't I use a class from external jar - java

When I created the jar file I wrote the following java file:
package myjar;
public class MyClass {
public static void hello() {
System.out.println("hello");
}
public static void main(String[] args) {
MyClass.hello();
}
}
I named the file MyClass.java.
I created a class file by typing "javac src/main/java/myjar/MyClass.java"
I generated a jar file by the command:
"jar cvf myjar.jar src/main/java/myjar/MyClass.class"
Now, I took the jar file and added it to Project Structure. The name of the jar is 'myjar':
and in the IDE I wrote "import myjar.MyClass" and the word 'myjar' was marked in red.
When I use 'MyClass.hello()' in the project, I get an error:
no main manifest
Do you know what I can to to load it successfully ?

You can only import some classes from your libraries on classpath into a Java source file, not a contents of a whole Java archive (JAR) file. So if you have inside myjar.jar file class Foo.class inside package (folder) bar, you can do
import bar.Foo;

After adding the .jar as a library in IntelliJ, you still need to add it to the module.
Then the library will appear in the module's list of dependencies.

Related

VSCode Import from JAR file cannot resolve class

We have a java app that needs to use a public class form a JAR file. After much frustration with the main application, we have created a simple repo here to try to figure out what is going on.
The overly simple file that ends up in the JAR file is as follows:
package com.mystuff.helpers;
public class printStuff {
public void showMsg(String msg) {
System.out.println(msg);
}
}
We create the JAR file with this command:
jar cvf MyJavaHelpers.jar com
The folder structure is as follows (the printStuff.java file is in the helpers folder):
A listing of the JAR contents is as follows:
jar tf MyJavaHelpers.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/mystuff/
com/mystuff/helpers/
com/mystuff/helpers/printStuff.java
com/mystuff/helpers/README.md
Finally, the program that we have to use this simple class is as follows:
package com.mystuff.testapp;
import com.mystuff.helpers.*;
// To build the JAR file
// jar cvf MyJavaHelpers.jar com
// To display the contents of the JAR file
// jar tf MyJavaHelpers.jar
public class testDriver {
public static void main(String[] args) {
System.out.println("Starting testDriver");
com.mystuff.helpers.printStuff ps = new com.mystuff.helpers.printStuff();
// testPrintStuff(ps);
// testPrintStuffAgain(ps);
}
/*
private static void testPrintStuffAgain(printStuff ps) {
ps.showMsg("This is a fine kettle of clams");
}
private static void testPrintStuff(printStuff ps) {
ps.showMsg("This is a fine kettle of fish");
}
*/
}
In VS Code (v 1.55.0) We have a Java Project to contain our TestDriver that looks like this:
Finally, the issue is that when we try to run the test driver, we get the message:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
com.mystuff.helpers.printStuff cannot be resolved to a type
com.mystuff.helpers.printStuff cannot be resolved to a type
at com.mystuff.testapp.testDriver.main(testDriver.java:15)
We have tried the command Clean Java Language Server Workspace which seems to indicate that it works, but we cannot get past this error.
Based on what we have looked at, the JAR file appears to be in the correct place (It is in the lib folder of the main app).
The import com.mystuff,helpers.; line does not show as an error, so it seems to us that it is found, however, the actual import of the printStuff class fails. We have tried the fully qualified class name as well as relying on the import and only using the short name. They both fail.
We have seem some guidance about setting the classpath, but have not been able to find how to do that explicitly in VS Code.
Of course, if we do not have this little helper in a JAR file, but just as a side-by-side in the same project, it works just fine. The issue that started us down this journey is trying to use a public class from a pre-packaged JAR file.
Any and all help is greatly appreciated. Thanks in advance.
Before adding the jar to library, you may run the command java -jar printStuff.jar to test if it could be executed successfully.
The error occurs because the class must be called with its fully qualified name. To be clear, the name of this class is not printStuff, It's com.mystuff.helpers.printStuff, so the right command should be:
Turn to the folder;
Compile .java file: javac com\mystuff\helpers\printStuff.java
Generate .jar: jar cvfe printStuff.jar com.mystuff.helpers.printStuff .\
Then readd it to referenced libraries and see if the error goes away.

Trying to run jar file from command line using classpath(for other libs) raises "Could not find or load main class", on Windows

I'm trying to run a jar file from command line on Windows using:
java -cp .;C:\java\empacotadoJars\Empac.jar;C:\java\empacotadoJars\ClienteEmpacotado.jar ClienteEmpacotado
It raises the exception:
Could not find or load main class ClienteEmpacotado
The classes are:
public class Empacotado{
public static void escrever(){
System.out.println("Chamndo metodo de classe Empacotado!");
}
}
public class ClienteEmpacotado{
public static void main(String args[]){
Empacotado.escrever();
}
}
Empacotado.class is inside Empac.jar and ClienteEmpacotado.class is inside ClienteEmpacotado.jar. I first zipped each one and then renamed to jar extension. Inside ClienteEmpacotado.jar I created META-INF folder with MANIFEST.MF file, which contains:
Manifest-Version: 1.0
Main-Class: ClienteEmpacotado
What might be wrong?
The problem was that I had used Winrar to make the zip files (then I renamed to jar extension). Using "jar cvf Package.jar Arq.class" to make the jars solved.

What is included when making a jar file?

When I build my project (using the Netbeans IDE) will it only take the main class, or will it include the other classes in the project even though they are not explicitly declared within the code for the main class?
All classes in a package are included in a jar file. You can cross-check it by following this:
Go to dist folder of the project.
Extract the jar file with any file archiver(eg: 7-zip, winrar, winzip).
The extracted folder contains all the contents that are included in a jar file.
Example:
Test is a main class
Test.java:
package test;
public class Test
{
public static void main(String[] args) {
// TODO code application logic here
}
}
There is another class: class1
class1.java:
package test;
public class class1
{
}
class1.java is not explicitly declared within the code for the main class(Test).But when I build this project in a Net-beans IDE and extracted the jar file(Test.jar).The jar contains:
class1.class
Test.class
What goes in a JAR and what remains out depends on the packaging agent, so this is definitely IDE-dependent, and also depends on the configuration options used to build the archive (for example if it's a lib JAR, if it's an executable JAR, if it's a WAR, and so on).
For example, Eclipse can package your compiled sources along with the JAR dependencies, but this also requires including some special class to load classes from JARs inside the distributed JAR.
Anyway, you can always customize the packaging phase, and you can extract the archive to see what it actually contains.

Editing a manifest With java

I have just started my first Java program. I have created a batch file to run my command line arguments. In this program I am writing a "HelloWorld" string with HelloWorld.java
class HelloWorld
{
public static void main(String [] args)
{
System.out.println("HelloWorld!!");
}
}
Now after I added java to my path I use the following in the .bat file.
javac HelloWorld.java //to complie
java HelloWorld //toRun
jar -cvf HelloWorld.jar HelloWorld.class //creating a archive
jar -xf HelloWorld.jar //Extracting and finding the manefest
From my jar file I now have to edit the manifest file and set the class I have just written as my main class for the jar file and I have done it as follow:
jar -cmf HelloWorld.jar Manifest.txt HelloWorld.class //Here is the problem
java -jar HelloWorld.jar //here I am trying to run it
pause
I cant seem to edit the manifest. Do I have a Command prompt error or did I mistype something?
The Manifest is a file named "MANIFEST.MF" in the META-INF directory. So, you need to have your final code look like this on the filesystem:
HelloWorld.class
WEB-INF
MANIFEST.MF
Then jar that up in its entirety.
Finally, you should also put your HelloWorld.class in to an actual package:
package pkg;
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
Then your final product will look like:
pkg
HellowWorld.class
META-INF
MANIFEST.MF
And your final class name will be pkg.HelloWorld.
Things simply work better with actual packages in Java, it's best to use them right away and avoid trouble.
Note: Oh my mistake, I didn't catch the use of the -m flag -- So used to larger projects where the Manifest is just part of the build artifact.

Running a Java Program from jar file not working if another package is used, classpath set

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.

Categories

Resources