I am trying to instrument a jar file (main.jar) with javaagent.jar using BCEL. basically where ever I find any aload in bytecode, I m trying to insert a function call to a static function called Fun() in class "someclass" using
if (opcode instanceof aload) {
iFactory.createInvoke("someclass", "fun", Type.VOID, new Type[]{}, Constants.INVOKESTATIC);
my "someclass" class reside in javaagent.jar
on executing
java -javaagent:javaagent.jar -jar main.jar
or
java -javaagent:javaagent.jar -jar main.jar javaagent.jar
or (I created a separate jar for my "someclass" called someclasscontained.jar)
java -cp someclasscontained.jar -javaagent:javaagent.jar -jar main.jar
I am getting
Exception in thread "main" java.lang.NoClassDefFoundError: someclass
error. i tried with -bootclasspath/p option but still not working. does anyone has any clue?
(1) all jar resides in same folder
2) this question may be similar to one question but solution is not correct/satisfactory for that question so please don't mark it duplicate )
If someclass is defined in a different jar file, you need to add it to the Boot-Class-Path list in your agent jar manifest file:
some.jar -> contains someclass.class
javaagent.jar -> contains your instrumenting classes and MANIFEST.MF file
MANIFEST.MF file should contain line like
Boot-Class-Path: javaagent.jar some.jar
Related
I need to compile and run simple code using the gson library, but I can't use Maven, Gradle or the IDE.
The directory contains Main.java and gson-2.9.0.jar
javac -cp gson-2.9.0.jar Main.java works correctly and creates Main.class
But when I run java -cp ./*: Main, I get
Error: Could not find or load main class Main.
Caused by: java.lang.ClassNotFoundException: Main
I also tried the following commands:
java -cp gson-2.9.0.jar Main
java -cp gson-2.9.0.jar: Main
java -cp ./gson-2.9.0.jar:./* Main
But all these commands give the same result. I've never had to run code from the command line without Maven or IDEA before, so I think it's the classpath specification that's the problem. What am i doing wrong here?
If your main class is in a package (has a package ... declaration), you need to include the package name in the java call, e.g. java -cp ... mypackage.Main.
Additionally, the java documentation says about -cp / --class-path:
As a special convenience, a class path element that contains a base name of an asterisk (*) is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR.
Therefore, using * for .class files does not work; instead you have to specify the directory name. Based on your question it looks like you are using Linux, and that the .class file and the JAR are in the same directory, so the following should work in your case:
java -cp gson-2.9.0.jar:. Main
(note the . after the :, indicating to include the current directory for the classpath)
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.
So I'm still a noob in Java and I'm experimenting around with a few things.
I recently created a .jar file for my class using jar cvf <name>.jar <source files> and then used that jar to compile my driver class (javac -cp <name>.jar Driver.java) though how do I now run that class using the jar?
I've tried the following 2 commands:
java Driver and,
java -cp <name>.jar Driver.
The first gives me a NoClassDefFoundError for the class used, whereas the latter just gave me a single line error.
Error: Could not find or load man class Driver
What am I doing wrong? Is it possible I'm confusing this for something else?
I'm trying to do as much as I can without the use of any IDE.
You should put jar file and compiler output into classpath and specify main class:
java -classpath "<name.jar>;classes" Driver
EDIT (thanks to Kayaman):
If you are running command from linux/unix you have to use ":" as separator (in Windows works ";"). "classes" is a path to folder containing compiler output.
When creating an executable jar ( jar which contain a class with the main method) you should tell the jar which is the mainClass to be executed and for that you should create a file called 'Manifest.mf'.
The file should contain this:
Main-Class: MyPackage.MyClass
And when creating the jar you should use this to include your manifest:
jar cfm MyJar.jar Manifest.mf MyPackage/*.class
And for launching your jar :
java -jar MyJar.jar
This question already has an answer here:
Exporting executable/runnable jar in eclipse
(1 answer)
Closed 7 years ago.
I just wrote Java console project , which i shoud pack as jar file. I googled it alot and found different solutions like (Eclipse) Project -> New Configuration -> e.t.c Then export as jar file using speciefied config. That's nice, but it's not what i need. After making repeatedly - it won't work. I tried to do same as mentioned here: click
Second Solution: create jar using manifest. Well it's much better, because i can specifiy entry point of main.class. But it's won't work due to can;t find out where's annother packages.
Upd: Launcher.class looks like this
package backpack.dao;
public class Launcher{
public static void main(String[] args){
Backpack.start();
}
}
My project structure:
src/backpack/dao/Item.java
/Backpack.java
/Chromo.java
src/backpack/main/launcher/Launcher.java
The Question is: What should i write in manifest instead of this:
Main-Class src/backpack/main/launcher/Launcher to make executable jar
successfully?
P.S Launcher class uses instances from Backpack.java
Please don't downgrade. I'm rookie
Thanks
What is the package of the Launcher.java? Have you included package name to the classname in manifest.txt?
Remember, when Launcher.java is in package "backpack.main.launcher" your classname in manifest.txt will be:
Main-Class src/backpack.main.launcher.Launcher
instead of:
Main-Class src/backpack/main/launcher/Launcher
Also, remember about this:
The text file must end with a new line or carriage return.
To check what exactly is wrong with your jar file run it in the command line using:
java -jar MyJar.jar
and paste here output with error message.
For more help you can check this example from Oracle: link
Edit:
I recreated your project structure and I have found the solution (at least I think I have :) )
Compile your code and go to the parent directory with compiled code (with *.class files, this should be "out" directory or something like this - depending from your IDE). For example: when your project is in some/path/src/backpack/main/launcher go to src directory.
Run command:
jar cvfe MyJar.jar backpack.main.launcher.Launcher -C . .
(Yes, two dots at the end)
This should create jar with name MyJar.jar and manifest file (-e flag) with main class backpack.main.launcher.Launcher. -C flag include all *.class files recursively from directory . (current one), so both from dao and launcher package.
Test jar: java -jar MyJar.jar
I use a jar file called korat.jar. I executed with the command line:
java -cp $CLASSPATH korat.Korat --visualize --class test.Add --args 3
The classpath contains the path of the jar and also the Add.class file.
I want to execute this jar in my own program java in netbeans IDE. I think I would use:
String []s={test.Add.class.getName(),"--visualize","--class","test.Add","--args","3"};
Korat.main(s);
I get this exception: java.lang.NoClassDefFoundError
What do you mean "to execute the jar in my own program"? The jar contains some classes, if they are in your class path, you can instantiate the classes themselves and invoke some methods. In that case, you should use test.Add class. But it seems like the class is not in your classpath - java.lang.NoClassDefFoundError.