Below is the code taken from http://doc.akka.io/docs/akka/2.2.3/AkkaScala.pdf
import akka.actor.Actor
object Greeter {
case object Greet
case object Done
}
class Greeter extends Actor {
def receive = {
case Greeter.Greet =>
println("Hello World!")
sender ! Greeter.Done
}
}
In it, it says :
How can I run this as a standalone within Eclipse ?
I've tried creating a new Run configuration, setting com.example.HelloWorld as the main class with the program argument being akka.Main but I receive "main class not found" exception.
Update :
Based on answer by TheTerribleSwiftTomato I have
input akka.Main into the Main class field, and
added com.example.HelloWorld as the sole argument in the Arguments tab.
but I receive below error :
Exception in thread "main" java.lang.ClassNotFoundException: com.example.HelloWorld
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:67)
at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:66)
at scala.util.Try$.apply(Try.scala:161)
at akka.actor.ReflectiveDynamicAccess.getClassFor(DynamicAccess.scala:66)
at akka.Main$.main(Main.scala:32)
at akka.Main.main(Main.scala)
I have added the akka Maven dependency, is there something else I'm missing ?
akka.Main is not an argument, it is the launcher class (i.e. the one that contains the main method). In this case, as described in the documentation, it will set up the ActorSystem instance and other necessary infrastructure.
So, in Eclipse, you would:
input akka.Main into the Main class field, and
add com.example.HelloWorld as the sole argument in the Arguments tab.
Re edit: I see two problems:
in the snippet you posted in the question, you don't actually appear to have the HelloWorld class from the example. Did you remember to include in your project?
even if you did remember to include it, there's a slight error in the HelloWorld class. It's missing the package declaration:
package com.example
Correct that (move it to the right package) and you should be on your way to writing Actor systems.
Related
I am trying to load class "SampleTest.class" from folder(C:\com\scheduler\jobs) in my current application, I could able to load class when it doesn't have package declaration.
The problem with when "SampleTest.class" has package declaration then I couldn't able to load and giving error No class found.
My current application when I am trying to load class :
**ReadInterfacesCount.java**
URL url = new URL("file:/C:/com/scheduler/jobs/");
ClassLoader cl = new URLClassLoader(new URL[]{url});
Class<?> aClass = cl.loadClass("SampleTest");
System.out.println("Interfaces count ==> "+aClass.getInterfaces().length);
SampleTest.class
package com.scheduler.jobs;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
public class SampleTest implements Serializable{
public static void main(String[] args) throws IOException{
System.out.println("From Sample Test");
}
}
When I run ReadInterfacesCount it is giving below error:
Exception in thread "main" java.lang.NoClassDefFoundError: SampleTest (wrong name: com/scheduler/jobs/SampleTest)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.test.ReadAllJavaClasses.getListeners(ReadAllJavaClasses.java:119)
at com.test.ReadAllJavaClasses.main(ReadAllJavaClasses.java:101)
When I remove package declaration in SampleTest file now I could able to load class.
Can anyone help me out?
Thanks,
Naresh Kallamadi.
As someone upvoted my comment, I'm converting that quick assumption to an answer
When Class.forName("SampleTest", ...) fails to instantiate a class named com.scheduler.jobs.SampleTest, but succeeds instantiating a class SampleTest, you might want to try Class.forName("com.scheduler.jobs.SampleTest", ...)
Edit: And as I wrote in the comment, it seems completely weird for me to digest code this way - I've never tried it. The next thing that comes to mind after your comment: When you want to load the class stored in C:/com/scheduler/jobs/SampleTest.class as com.scheduler.jobs.SampleTest, you might need to give C:/ as the path to the classloader, because that's the root of where it should search for a class of this package/name.
Coming back to the mentioned weirdness of the code: I don't trust any business level code that explicitly deals with classloading. Classloading is an infrastructure problem, and while you might solve the problem at hand, I believe that you're solving a completely wrong problem - you rather have severe problems with your underlying architecture (which can't be solved in this question)
I tried to create a custom class String in java.lang package in my eclipse workspace.
initially I suspected that a same class in same package can not be created but to my utter surprise I was able to create a class (String) in same package i.e. java.lang
Now I am confused
1) why is it possible and
2) what can be the reason if that is allowed.
3) what will be the use if this type of creation of java classes is allowed in Java.
You can create a new class in java.lang package. If it was forbidden how Oracle developers would be able to develop Java at all? I am sure they use the same javac as we do.
But you will not be able to load it, because java.lang.ClassLoader (that any classloader extends) does not allow it, every class being loaded goes through this check
...
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException
("Prohibited package name: " + name.substring(0, name.lastIndexOf('.')));
}
...
so you will end up in something like
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:649)
at java.lang.ClassLoader.defineClass(ClassLoader.java:785)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
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:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at Test1.main(Test1.java:11)
As for classes that shadow existing classes like your java.lang.String they cannot be loaded because the System ClassLoader (default one) uses "parent first" strategy, so java.lang classes will be loaded from rt.jar with bootstrap classloader. So you will need to replace String.class in rt.jar with your version. Or override it using -Xbootclasspath/p: java option which prepends paths to bootstrap class loader search paths. So you can
1) copypaste real String.java content into your String.java
2) change a method, eg
public static String valueOf(double d) {
return "Hi";
}
and compile your String.java
3) create a test class
public class Test1 {
public static void main(String[] args) throws Exception {
System.out.println(String.valueOf(1.0d));
}
}
4) run it as
java -Xbootclasspath/p:path_to_your_classes Test1
and you will see
Hi
This is called class shadowing.
1.) It is possible because java classes are not statically linked, but linked at class load time.
2.) If it was not allowed, then the whole class loading would be a lot more difficult to achieve. Then for example you would also have to build your project against a specific Java version. because Java classes may change from version to version. This isn't going to be a maintainable approach.
3.) osgi makes use of this to be able to load different versions of the same bundle. Another common use case is to replace buggy classes in frameworks, where no other workaround is possible. However this technique should be used carefully, because errors might be hard to debug.
Please note that however shadowing classes in the java.* packages is not allowed, as this would break the Java security sandbox. So you are going to have problems at runtime.
Yes you can create the package with name java.lang and also Class named as String.
But you wont be able to run your String class.
1) why is it possible : Compiler will compile your class successfully.
2) what can be the reason if that is allowed : You have a valid name for your package and class so compiler doesn't complain.
3) what will be the use if this type of creation of java classes is allowed in Java : But there is not much use of this String class. Bootstrap class loader will load class from the sun's java.lang package. So your custom String class will not get loaded and hence it fails during run.
Bootstrap class loader is part of JVM implementation and it loads the classes of Java API (which includes java.lang.String). Also for each class which gets loaded, JVM keeps track of which class loader whether bootstrap or user-defined - loaded the class. So any attempt to load a custom String class will fail as String class is already loaded.
I am not clear on the following:
A class is loaded by JVM when needed, like lazy initialization, right?
Now if class A does an import of class B which class B actually is not in the file system (e.g. B.class was deleted or not delivered or any reason)
then does class A get loaded and runs if no method of class B is called?
Or class A is not able to run at all since the imports can not be resolved?
Or class A is loaded and run up to a certain point?
import statement is only important for the compiler. In bytecode all references to other classes are fully qualified. That's why superflous imports don't matter at runtime.
In your case JVM will try to load all classes that are required to load and verify A, so it will try to load B immediately, but dependant classes are loaded lazily only when they are needed. Check out the following example:
public class A {
public static void bar() {
new B().foo();
}
public static void main(String[] args) {
//bar();
}
}
Compile A.java and delete B.class. Without calling bar() method your program will run just fine. But once you uncomment piece of code actually using B class you'll get nasty:
Exception in thread "main" java.lang.NoClassDefFoundError: B
at A.bar(A.java:4)
at A.main(A.java:8)
Caused by: java.lang.ClassNotFoundException: B
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:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 2 more
If B is not available, you'll get NoClassDefFound or similar.
If A.class require B.class which is missing. A.class can not be loaded.
Loading class is a recursion operation.
When A.class require B.class, the JVM search B.class in PermGen. If B.class is loaded and store in PermGen, JVM will not reload the B.class but get it from PermGen directly, otherwrise the JVM will load B.class recursively.
When JVM can not find B.class, it throw NoClassDefFoundError.
See more about NoClassDefFoundError in [Java Specification] :page 319.
You will get NoClassDefFoundError when you call the method that uses the definition of B.class. This will cause the class loader to search for B.class and load it in memory.
AFAIK there is one exception to this rule, Annotations. When you have an annotation that cannot be found at run time it will be ignored in some cases, see: Why doesn't a missing annotation cause a ClassNotFoundException at runtime?
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I am trying to run a class, but I get the following error:
java.lang.NoClassDefFoundError: MyClass
Caused by: java.lang.ClassNotFoundException: MyClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Exception in thread "main"
It happens, although the main method is in MyClass and I run directly this class.
Why is this class not found, although I launch the program from it?
Here is some code:
public class MyClass extends A implements B{
public MyClass() throws Exception {
//make some initializations
}
public static void main(final String[] args) throws Exception {
MyClass myClass = new MyClass();
//do stuff with myClass
}
}
PS: I am using Eclipse Indigo.
EDIT
I have run the class in the Command Line twice:
D:\Eclipse JEE\Workspace2\Example\target\classes\com\example\main>java com.example.main.MyClass
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/main/MyClass
Caused by: java.lang.ClassNotFoundException: com.example.main.MyClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: com.example.main.MyClass. Program will exit.
D:\Eclipse JEE\Workspace2\Example\target\classes\com\example\main>java GeoDAOImpl
Exception in thread "main" java.lang.NoClassDefFoundError: MyClass(wrong name: com/example/main/MyClass)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: MyClass. Program will exit.
You haven't really given us enough information to say for sure, but my guess is that either:
You're not giving the right fully-qualified class name
Your class isn't on the classpath
For an example of the first case, if your code looks like this:
package foo;
public class MyClass {
public static void main(String[] args) {
}
}
Then you should be running:
java foo.MyClass
EDIT: With the extra information provided, I suspect I know what's happened. I suspect the class was created not in a package, and a Run Configuration was created which just runs MyClass. It's now been moved into com.example.main, but without the Run Configuration being updated.
Go into the Run Configuration editor (click on the dropdown next to the "run" button, and select Run Configurations...) and find "MyClass", then check which class is going to be run, and edit it to put the right package name in.
You first need to compile your source file if you haven't already done so. Assuming that your class MyClass is not in a package, and you are in the directory that contains the source file MyClass.java, compile it with:
javac MyClass.java
You should now have a file named MyClass.class.
Then, to run it, you need to make sure that the directory that contains the MyClass.class file is in the classpath. If you do not have the CLASSPATH environment variable set, Java will by default look in the current directory, so you should be able to run it with:
java MyClass
If this doesn't work, you can explicitly put the current directory . in the classpath using the -cp option:
java -cp . MyClass
I wrote a java program to test RESTful web services by using Netbeans7.0.1 and it works fine there. Now I wrote the build.xml file to compile the code and when I try to run the generated .class file I always got this exception:
Exception in thread "main" java.lang.NoClassDefFoundError: ClientREST (wrong name: clientrest/ClientREST)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: ClientREST. Program will exit.
The name and path are correct, so any thoughts why I'm getting this exception?
Exception in thread "main" java.lang.NoClassDefFoundError: ClientREST
So, you ran it as java ClientREST. It's expecting a ClientREST.class without any package.
(wrong name: clientrest/ClientREST)
Hey, the class is trying to tell you that it has a package clientrest;. You need to run it from the package root on. Go one folder up so that you're in the folder which in turn contains the clientrest folder representing the package and then execute java clientrest.ClientREST.
You should not go inside the clientrest package folder and execute java ClientREST.
I encountered this error using command line java:
java -cp stuff/src/mypackage Test
where Test.java resides in the package mypackage.
Instead, you need to set the classpath -cp to the base folder, in this case, src, then prepend the package to the file name.
So it will end up looking like this:
java -cp stuff/src mypackage.Test
To further note on Garry's reply: The class path is the base directory where the class itself resides. So if the class file is here -
/home/person/javastuff/classes/package1/subpackage/javaThing.class
You would need to reference the class path as follows:
/home/person/javastuff/classes
So to run from the command line, the full command would be -
java -cp /home/person/javastuff/classes package1/subpackage/javaThing
i.e. the template for the above is
java_executable -cp classpath the_class_itself_within_the_class_path
That's how I finally got mine to work without having the class path in the environment
Probably the location you are generating your classes in doesnt exists on the class path. While running use the jvm arg -verbose while running and check the log whether the class is being loaded or not.
The output will also give you clue as to where the clasess are being loaded from, make sure that your class files are present in that location.
Try the below syntax:
Suppose java File resides here: fm/src/com/gsd/FileName.java
So you can run using the below syntax:
(Make current directory to 'fm')
java src.com.gsd.FileName
Suppose you have class A
and a class B
public class A{
public static void main(String[] args){
....
.....
//creating classB object
new classB();
}
}
class B{
}
this issue can be resolved by moving class B inside of class A and using static keyword
public class A{
public static void main(String[] args){
....
.....
//creating class B
new classB();
static class B{
}
}
Here is my class structure
package org.handson.basics;
public class WithoutMain {
public static void main() {
System.out.println("With main()...");
}
}
To compile this program, I had to use absolute path. So from src/main/java I ran:
javac org/handson/basics/WithoutMain.java
Initially I tried with the below command from basics folder and it didn't work
basics % java WithoutMain
Error: Could not find or load main class WithoutMain
Caused by: java.lang.NoClassDefFoundError: org/handson/basics/WithoutMain (wrong name: WithoutMain)
Later I went back to src\main\java folder and ran the class with relevant package structure, which worked as expected.
java % java org.handson.basics.WithoutMain
With main()...
I also have encountered this error on Windows when using Class.forName() where the class name I use is correct except for case.
My guess is that Java is able to find the file at the path (because Windows paths are case-insensitive) but the parsed class's name does not match the name given to Class.forName().
Fixing the case in the class name argument fixed the error.