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 {
//...
}
Related
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...
I have a maven project in the following structure.
TestRun
|
|--src/main/java/com/main/CallAddNumbers.java (Package - Com.main)
|
|--src/test/java/com/test/RunTest.java (package com.test)
and here is the sample program
package com.main;
public class CallAddNumbers {
public static void main(String[] args) {
com.test.AddNumbers.addNumbers(5, 4);
}
}
package com.test;
public class AddNumbers {
public static void addNumbers (int a, int b){
System.out.println(a+b);
}
}
When I am calling addNumbers method from main, I am ending up with the following error. May be something simple, but can't figure it out.
Exception in thread "main" java.lang.NoClassDefFoundError: com/test/RunTest
at com.main.CallAddNumbers.main(CallAddNumbers.java:6)
Caused by: java.lang.ClassNotFoundException: com.test.RunTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 1 more
you said it might be something simple, just wanted to check that this is your actual file structure before looking any further!
|
|--src/main/java/com/main/CallAddNumbers.java (Package - com.main)
|
|--src/test/java/com/test/addNumbers.java (package com.test)
Add this import statement to the CallAddNumbers class
import test.java.com.test.AddNumbers;
It will work fine. Btw better dont write production codes in test package
Why does the following code cause ClassNotFoundException?
public class App02 {
public static class A {
}
public static void main(String[] args) throws ClassNotFoundException {
try {
System.out.println("A.class.getCanonicalName() = " + A.class.getCanonicalName());
Class c = Class.forName("tests.App02.A"); //error on this line
System.out.println(c.getName());
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Output:
A.class.getCanonicalName() = tests.App02.A
java.lang.ClassNotFoundException: tests.App02.A
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at tests.App02.main(App02.java:15)
Try Class c = Class.forName("tests.App02$A"). It's not a top-level class, so use $ to locate it.
You need to use $ to access the nested class:
Class c = Class.forName("tests.App02$A");
When you compile your class, you will notice that the nested class is named as: App02$A.class, under package tests. It would make more sense then.
Because you are using a canonical name, but you should use name (A.class.getName()).
In your case you should use Class c = Class.forName("tests.App02$A");
There is a helpful util in commons-lang which support these classes:
org.apache.commons.lang3.ClassUtils.get("tests.App02.A")
I am new to reflection and to practice, I downloaded a random Java project from a website. I decided to find out which class has the main method so I wrote the following code:
package reflection;
import java.io.IOException;
import java.lang.reflect.*;
import java.nio.file.*;
public class FindMethods {
public static void main(String[] args) throws IOException{
if(args.length==0){
System.out.println("Exiting");
System.exit(1);
}else{
Path p = Paths.get(args[0]);
DirectoryStream<Path> allClassFiles = Files.newDirectoryStream(p, "*.class");
for(Path each : allClassFiles){
// System.out.println(each.getFileName());
try {
findMethods(each.getFileName().toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
public static void findMethods(String file) throws ClassNotFoundException{
System.out.println(file);
Class c = Class.forName(file);
Method[] m = c.getDeclaredMethods();
for(Method each : m){
System.out.println(each.toString());
}
}
}
System.out.println(each.getFileName()); properly returns the .class files in the folder however, it is interspersed with stack trace of ClassNotFoundException
The classes are as follows:
Addwindow$1.class
Addwindow$2.class
Addwindow.class
Authorwindow.class
clsConnection.class
clsSettings$1.class
clsSettings.class
Deletewindow$1.class
Deletewindow$2.class
Deletewindow.class
Editwindow$1.class
Editwindow$2.class
Editwindow.class
Emprptwindow$PrintCommand.class
Emprptwindow.class
Helpwindow.class
LoginFrame$1.class
LoginFrame.class
MainMenu$1.class
MainMenu$2.class
MainMenu.class
Payrptwindow.class
printwindow$1.class
printwindow.class
Settingswindow$1.class
Settingswindow.class
What changes do I need to make to the code to get the methods from each class ?
Stack trace:
java.lang.ClassNotFoundException: Settingswindow
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at reflection.FindMethods.findMethods(FindMethods.java:33)
at reflection.FindMethods.main(FindMethods.java:22)
Random project being talked about:
http://projectseminar.org/java-projects/payroll-accounting-system/98/
.class is part of the filename, but it isn't part of the class name. You need to strip it before passing it to Class.forName.
Another issue is that forName expects packages to be separated using periods, rather than than slashes or whatever directory separator your filesystem uses. If everything is in the default package, this shouldn't be an issue though.
If it's still not working, you should double check the classpath.
Class names that contain a $ are anonymous classes within the outer class (determined by the name to the left of the $). You can safely ignore those in your search for main. Just test for the presence of a $ in the class names in your main loop and skip the processing.
Without knowing more about what app you are looking at, I can't say why your code can't find some of the other classes (like clsConnection).
There is a problem in this approach - you load all project's classes. It is better to analize classes without loading them. There are tools for that. Here's what we can do with http://www.jboss.org/javassist
public static void findMethods(String file) throws Exception {
ClassPool cp = ClassPool.getDefault();
try (InputStream is = new FileInputStream(file)) {
CtClass cc = cp.makeClass(is);
for (CtMethod m : cc.getMethods()) {
System.out.println(m);
}
}
}
Whatever I do I cannot create new instance of class Serwer. Please help, somehow constructor is invisible. I don't understand why is it so. The constructor is public and everything is coded in one file.
I just get this:
java.rmi.StubNotFoundException: Stub class not found: Serwer_Stub; nested exception is:
java.lang.ClassNotFoundException: Serwer_Stub
at sun.rmi.server.Util.createStub(Unknown Source)
at sun.rmi.server.Util.createProxy(Unknown Source)
at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.exportObject(Unknown Source)
at javax.rmi.PortableRemoteObject.exportObject(Unknown Source)
at javax.rmi.PortableRemoteObject.<init>(Unknown Source)
at Serwer.<init>(Serwer.java:13)
at Serwer.main(Serwer.java:35)
Caused by: java.lang.ClassNotFoundException: Serwer_Stub
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
... 10 more
CLASS
import java.rmi.RemoteException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.rmi.PortableRemoteObject;
public class Serwer extends PortableRemoteObject implements MyInterface {
public Serwer() throws RemoteException {
super();
try{
Serwer ref =
new Serwer();
Context ctx = new InitialContext();
ctx.rebind("myinterfaceimplementacja", ref);
}catch(Exception e){e.printStackTrace();}
}
#Override
public String echo(String napis) throws RemoteException {
return "echo" + napis;
}
#Override
public int dodaj(int wrt1, int wrt2) throws RemoteException {
return wrt1 + wrt2;
}
public static void main(String[] args){
try {
new Serwer();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
There are two bugs in your code. The first one is the obvious infinite recursion in the Serwer constructor, where you are calling the constructor again and again. This can be fixed by removing that line from the constructor and replace ref with this on the following line:
public class Serwer extends PortableRemoteObject implements MyInterface {
public Serwer() throws RemoteException {
super();
}
#Override
public String echo(String napis) throws RemoteException {
return "echo" + napis;
}
#Override
public int dodaj(int wrt1, int wrt2) throws RemoteException {
return wrt1 + wrt2;
}
public static void main(String[] args){
try {
Serwer ref = new Serwer();
// Context ctx = new InitialContext();
// ctx.rebind("myinterfaceimplementacja", ref);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
However, this bug is unrelated to the ClassNotFoundException you got. What causes the exception is that you use PortableRemoteObject as the base class of your remote implementation. Normally in Java RMI, the stub class (Serwer_Stub) is generated automatically when you export (instantiate) the remote object. But the PortableRemoteObject is an exception to this case. You can solve this two ways:
As Kumar suggested, replace the javax.rmi.PortableRemoteObject with java.rmi.server.UnicastRemoteObject. This way the stub object gets created automatically, and the above code will run happily, I tested it.
public class Serwer extends UnicastRemoteObject implements MyInterface {
If for some reason you must use PortableRemoteObject, then you should generate the stub class manually by using the RMI compiler (rmic) tool that are shipped with the JDK.
First, you compile the Serwer class:
javac Serwer.java
This will generate the Serwer.class file. Then you call the RMIC tool to generate the stub class:
rmic Serwer
This will generate the Serwer_Stub.class file. Now you can run your server:
java Serwer
I also tested this, it starts without any exceptions.
Note that there is another bug in your code with the usage of the Java Naming, causing another exception (NoInitialContextException), but that is also unrelated with the question, that's why I commented it out in the code above. Since I'm no expert in javax.naming, it's up to someone else to help you with that.
Maybe you intended to use RMI registry instead of using Naming by mistake. RMI registry is the native way to bind and lookup remote objects in Java RMI. In this case you should replace the
Context ctx = new InitialContext();
ctx.rebind("myinterfaceimplementacja", ref);
lines with the appropriate RMI registry code:
Registry reg = LocateRegistry.createRegistry(1099);
reg.rebind("myinterfaceimplementacja", ref);
This will create the RMI registry for you on the standard port (1099). If you run your program, the registry will be created and your remote object will be exported and registered under the given name.
The other way is to write
Registry reg = LocateRegistry.getRegistry();
This makes your program to find an existing registry that is already running. You must start the RMI registry before running your program, by calling the remiregistry tool, that is also part of the JDK:
rmiregistry
Now you can compile and you start your program:
javac Serwer.java
java Serwer
It will start and register your remote object implementation in the registry, making it available to be looked up by the clients.