I've built an application with two modes:
Used from command line
Used from Ant
It works well from command line but from ANT the error is a surprise, the Java loader can't find the main class and the exception was thrown from the main class!
Extract of main class
package hpms.app.mon.client;
import ....;
public class MonitorMainFrame extends Application implements ProcessListener {
....
public static void main( String[] args ) throws Exception {
final Class<?> c = Class.forName( MonitorMainFrame.class.getName());
/* The class was found and we print the constructor */
System.err.println( c.getConstructor());
launch( args ); // line 544
}
}
Build Execution
Buildfile: D:\dev\java\2014\hpms.app.mon\build.xml
compile-sample:
run-servers:
BUILD SUCCESSFUL
Total time: 1 second
Buildfile: D:\dev\java\2014\hpms.app.mon\build.xml
compile-sample:
run-client:
[monitor-client] public hpms.app.mon.client.MonitorMainFrame() throws java.lang.Exception <==== Trace of the constructor object
BUILD FAILED
D:\dev\java\2014\hpms.app.mon\build.xml:112: java.lang.RuntimeException: java.lang.ClassNotFoundException: hpms.app.mon.client.MonitorMainFrame
at javafx.application.Application.launch(Application.java:260)
at hpms.app.mon.client.MonitorMainFrame.main(MonitorMainFrame.java:544)
at hpms.app.mon.client.ant.AntTask.execute(AntTask.java:79)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="jar">
...
<taskdef
onerror ="ignore"
name ="monitor-client"
classpath="bin"
classname="hpms.app.mon.client.ant.AntTask" />
<target name="run-client" depends="compile-sample" description="...">
<monitor-client
minimized="true"
autostart="true">
...
How a Class Not Found Exception can be thrown from the class itself?
I suppose the Java class loader has loaded the class and the Ant class loader hasn't...
Related
public class demoRunner extends CommandLineJobRunner {
public static void main(String[] args) throws Exception {
// initialize fileappender here
String logFile = args[args.length - 1].split("=")[1];
DemoAppender.initializeAppender(logFile);
CommandLineJobRunner.main(args);
}
}
Run As VM argument : META-INF/spring/student.xml student
student is a job
Location of demoRunner.java: demoBatchJob\src\main\java\com\ncs\sma\runner\demoRunner.java
Location of stduent.xml: demoBatchJob\src\main\resources\META-INF\spring\student.xml
Exception:
Error: Could not find or load main class META-INF.spring.student.xml
Caused by: java.lang.ClassNotFoundException: META-INF.spring.student.xml
Try putting it outside META-INF and add the below VM argument -
spring/student.xml
Run As VM argument : META-INF/spring/student.xml student
You need to select demoRunner as the main class to run and pass the input file and job name META-INF/spring/student.xml student as "Program argument" and not as "VM argument".
package freshjuice;
class FreshJuice {
enum FreshJuiceSize { SMALL, MEDIUM, LARGE }
FreshJuiceSize size;
}
}
public class FreshJuiceTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
FreshJuice juice = new FreshJuice();
juice.size = FreshJuice.FreshJuiceSize.MEDIUM ;
System.out.println("Size: " + juice.size);
// TODO code application logic here
}
}
This is the error message I am getting:
Error: Main method not found in class freshjuice.FreshJuice, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
C:\Users\TheGODMasterDu\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 2 seconds)
Your file must be called FreshJuiceTest.java, because that is the class where your main method is located.
Your file name is FreshJuice.java which does not contains main()
In short netbeans looking for main() in your first class
Either change your file name to FreshJuiceTest.java or swap the code of your classes and define FreshJuice.java as public and remove public from second class
I have a class named MyCollection in the directory
C:\Users\risha\OneDrive\RishavAgarwal\MyJavaClasses\utility\
inside the package - MyJavaClasses.utility
I have written a class named P22_Generics1 in the directory
C:\Users\risha\OneDrive\Documents\Java Practice\
This class uses the above created class.
I successfully compiled it using the command
javac P22_Generics1.java -cp C:\Users\risha\OneDrive\RishavAgarwal
Now, when I try to run it using the command java P22_Generics1, this error occurs
Exception in thread "main" java.lang.NoClassDefFoundError: MyJavaClasses/utility/MyCollection
at P22_Generics1.main(P22_Generics1.java:5)
Caused by: java.lang.ClassNotFoundException: Java.utils.Collection
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
What can I do to execute it successfully?
The P22_Generics1.java looks like this
import MyJavaClasses.utility.MyCollection;
public class P22_Generics1 {
public static void main(String[] args) {
MyCollection<Integer> collection = new MyCollection<>();
collection.add(1);
collection.add(4);
collection.add(10);
collection.add(5);
System.out.println(collection);
System.out.println(collection.get(3) + " " + collection.size());
}
}
The MyCollection.java starts like this
package MyJavaClasses.utility;
import java.util.*;
/**
* #author Rishav Agarwal
* #param <T> This describes the Type parameter
*/
public class MyCollection<T> implements Cloneable {
//...
}
i am struggling since days on a simple project that i just can't get to run.
My goal is to extend the functionality of a .jar-File in order to get more information about the inner workings of that jar. The .jar is not open source.
I came accross a lot of different concepts to "inject" my own code into the jvm like the "ASM"-Library, BECL, Javassist and finally AspectJ.
AspectJ caught my attention as it seems to be easier to use and more high level. To try how AspectJ is working before using it with the closed source .jar, i set up Test-Projects:
Project1:
To test it, i wanted to create a simply project containing one Class that should be compiled and packed to a .jar-File. This class should later be monitored using the Aspect. I took the Source Code of this Class from an example on the internet: https://github.com/Nosfert/AspectJ-Tutorial-jayway
The file content of the class looks like this:
YourClass.java:
package com.test.java.instrumentation;
public class YourClass {
public static void main(String[] args) {
YourClass yourClass = new YourClass();
yourClass.yourMethodBefore();
yourClass.yourMethodAfter();
yourClass.yourMethodAround(1);
yourClass.yourMethodAround(1,"Test");
}
public void yourMethodBefore() {
System.out.println("Executing TestTarget.yourMethodBefore()");
}
public void yourMethodAfter(){
System.out.println("Executing TestTarget.yourMethodAfter()");
}
public void yourMethodAround(Integer i){
System.out.println("Executing TestTarget.yourMethodAround()");
System.out.println("i : "+i);
}
public void yourMethodAround(Integer i,String x){
System.out.println("Executing TestTarget.yourMethodAround()");
System.out.println("i : "+i);
System.out.println("x : "+x);
}
}
I compile the code with the following command:
javac -d bin -cp ./src/ ./src/com/test/java/instrumentation/YourClass.java
The command runs without errors.
In the next step i created a Manifest file containing the necessary information to run the Class in a .jar-File:
MANIFEST.MF:
Manifest-Version: 1.0
Main-Class: com.test.java.instrumentation.YourClass
Built-By: Me
Build-Jdk: 1.8.0_131
In the next step i create a .jar:
cd bin\
jar cvfm program.jar ..\meta-inf\manifest.mf .
The .jar can be successfully executed via:
java -jar program.jar
The output looks like this:
Executing TestTarget.yourMethodBefore()
Executing TestTarget.yourMethodAfter()
Executing TestTarget.yourMethodAround()
i : 1
Executing TestTarget.yourMethodAround()
i : 1
x : Test
So far so good. Step 1 is completed. This is the example-application that should later be expanded with additional functionality using AspectJ's Load Time Weaving.
Project2:
In the next step i want to create the AspectJ .jar-File containing my code to expand the functionality of Project1:
The contents of Priject2 (YourAspect.java) is the following:
package com.test.java.instrumentation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.JoinPoint;
#Aspect
public class YourAspect {
//Patterns
//blank = modifier (public/private/protected or default(blank) should be looked for
//* = return type to look for. Void/Object/Primitive type
//com.jayway.YourClass.yourMethodBefore(..) = PackageName . ClassName . methodName (parameters)
#Before("execution (* com.test.java.instrumentation.YourClass.yourMethodBefore(..))")
//JointPoint = the reference of the call to the method
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("YourAspect's BeforeAdvice's body is now executed Before yourMethodBefore is called.");
}
//Patterns
//public = look for the specific modifier named public
//!Object = Basically we are looking for void or primitives. But if we specified Object we could get a good pattern
//com.jayway.YourClass.yourMethodBefore(..) = PackageName . ClassName . methodName (parameters)
#After("execution (public !Object com.test.java.instrumentation.YourClass.yourMethodAfter(..))")
public void afterAdvice(JoinPoint joinPoint) {
System.out.println("YourAspect's afterAdvice's body is now executed After yourMethodAfter is called.");
}
//Patterns
//!private = look for any modifier that's not private
//void = looking for method with void
//com.jayway.YourClass.yourMethodBefore(..) = PackageName . ClassName . methodName (parameters)
#Around("execution (!private void com.test.java.instrumentation.YourClass.yourMethodAround(Integer,..))")
//ProceedingJointPoint = the reference of the call to the method.
//The difference between ProceedingJointPoint and JointPoint is that a JointPoint can't be continued (proceeded)
//A ProceedingJointPoint can be continued (proceeded) and is needed for an Around advice
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
//Default Object that we can use to return to the consumer
Object returnObject = null;
try {
System.out.println("YourAspect's aroundAdvice's body is now executed Before yourMethodAround is called.");
//We choose to continue the call to the method in question
returnObject = joinPoint.proceed();
//If no exception is thrown we should land here and we can modify the returnObject, if we want to.
} catch (Throwable throwable) {
//Here we can catch and modify any exceptions that are called
//We could potentially not throw the exception to the caller and instead return "null" or a default object.
throw throwable;
}
finally {
//If we want to be sure that some of our code is executed even if we get an exception
System.out.println("YourAspect's aroundAdvice's body is now executed After yourMethodAround is called.");
}
return returnObject;
}
//Patterns
//blank = modifier (public/private/protected or default(blank) should be looked for
//* = return type to look for. Void/Object/Primitive type
//com.jayway.YourClass.yourMethod*(..) = PackageName . ClassName . * (parameters)
//Where the "*" will catch any method name
#After("execution ( * com.test.java.instrumentation.YourClass.*(..))")
//JointPoint = the reference of the call to the method
public void printNewLine(JoinPoint pointcut){
//Just prints new lines after each method that's executed in
System.out.print("\n\r");
}
}
I also created a MANIFEST.FM:
Manifest-Version: 1.0
Main-Class: com.test.java.instrumentation.YourAspect
Built-By: Me
Build-Jdk: 1.8.0_131
And a aop.xml:
<aspectj>
<aspects>
<aspect name="com.test.java.instrumentation.YourAspect"/>
</aspects>
<weaver options="-XlazyTjp">
<include within="com.test.java.instrumentation..*"/>
</weaver>
</aspectj>
I can compile the class successfully with the following command:
javac -cp ./lib/aspectjrt.jar;.lib/aspejctjweaver.jar;./src;. -d ./bin/ ./src/com/test/java/instrumentation/YourAspect.java
The resulting classfile is packaged together with the Manifest and the aop.xml into a .jar:
cd bin\
jar cvfm aspect.jar ..\meta-inf\manifest.mf ..\meta-inf\aop.xml .
When i try to run the example-program (Project1) and try to weave the aspect (Project2), i am using the following command:
java -Daj.weaving.verbose=true -Dorg.aspectj.weaver.showWeaveInfo=true -javaagent:./Aspect/lib/aspectjweaver.jar -cp ./Aspect/lib/aspectjrt.jar;./Aspect/lib/aspejctjtools.jar;. -jar ./JavaProgram/bin/program.jar
The load fails and the resulting error is the following:
[AppClassLoader#18b4aac2] info AspectJ Weaver Version 1.8.10 built on Monday Dec 12, 2016 at 19:07:48 GMT
[AppClassLoader#18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader#18b4aac2
[AppClassLoader#18b4aac2] info no configuration found. Disabling weaver for class loader sun.misc.Launcher$AppClassLoader#18b4aac2
Executing TestTarget.yourMethodBefore()
Executing TestTarget.yourMethodAfter()
Executing TestTarget.yourMethodAround()
i : 1
Executing TestTarget.yourMethodAround()
i : 1
x : Test
How can i injecte my aspect (Project2) into the running program.jar (Project1)?
Do you have any ideas?
I attached all the files including Sourcecode and Manifests that i created (Both projects) as a .zip-File in the following link, so you can also try out what i did so far. This might help you to spot my errors easier. The project is designed to run on windows commandline.
Link: Downloadlink of my Projects
Thank you very much for your Ideas!
I have a class ExcelReadWrite that runs fine when I run it through eclipse.But when I try to run it from command line I need to set classpath of dependent classes.
set CLASSPATH=C:\Users\NICSI\.m2\repository\org\apache\poi\poi-ooxml\3.11\poi-ooxml-3.11.jar;C:\Users\NICSI\.m2\repository\org\apache\poi\poi\3.11\poi-3.11.jar;
After setting class path it compiles successfully but when I execute my class then this exception occurs.
Error: Could not find or load main class ExcelReadWrite
public class ExcelReadWrite {
public static void main(String[] args) {
String inputFile=args[0];
String outputFile=args[1];
System.out.println("inputFile 0 "+inputFile);
System.out.println("outputFile 0 "+outputFile);
transformExcelFile(inputFile,outputFile);
//transformExcelFile("E:\\excel\\inputFile.xlsx","E:\\excel\\outputFile.xlsx");
}
}
I use following command to compile and execute my class
E:\excelTest>javac ExcelReadWrite.java
E:\excelTest>java ExcelReadWrite
Error: Could not find or load main class ExcelReadWrite
You have to add the actual Directory to your classpath:
E:\excelTest>java -cp .;%CLASSPATH% ExcelReadWrite