How do I run a Java class in a package? - java

I have two java classes as follows
App1 without a package:
class App1 {
public static void main(String[] args) {
System.out.println("App1 hello world...");
}
}
App2 in a package:
package java.java.package1;
class App2 {
public static void main(String[] args) {
System.out.println("App2 hello world...");
}
}
I can compile them both:
D:\javaTest>javac App1.java
D:\javaTest>javac App2.java
However, I can only run the first one:
D:\javaTest>java App1
App1 hello world...
D:\javaTest>java java.java.package1.App2
Exception in thread "main" java.lang.NoClassDefFoundError: java/java/package1/App2
Caused by: java.lang.ClassNotFoundException: java.java.package1.App2
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)
Could not find the main class: java.java.package1.App2. Program will exit.
How can I run App2?

If you put the source in an appropriate directory hierarchy matching the package name (D:\javaTest\java\java\package1\App1.java), and compile/run from the root of the hierarchy (D:\javaTest), you wouldn't have this problem:
D:\javaTest>javac java\java\package1\App1.java
D:\javaTest>java java.java.package1.App1
App2 hello world...
You can also compile using the -d option so that the classes are moved into such a directory hierarchy:
javac -d . App2.java
java java.java.package1.App2
Note you shouldn't use a package name starting with java, and later versions of the JDK will throw a SecurityException. See this question for more information.

You create a new directory. This is the directory containing your work, and is not the start of your packages.
For instance, I create folder /terri to start.
I then create the folder structure /clarie/andrea under it.
My package is going to be called claire.andrea in this example.
Normal package names start with com and then a company name or something like that (or java for standard java packages, so don't use that: like java.lang.*).
In the andrea folder, I create a java file called Saluton.java with the class Saluton (which just print hello). The class name and the filename must match.
To compile, from the terri/ folder: javac .\claire\andrea\Saluton.java
This will create a Saluton.class in the \terri\claire\andrea\Saluton.class
To run: (again from /terri), I do: java -cp . claire.andrea.Saluton
Which says, use class path from my current directory.
My main program is in the package claire.andrea and the Class name is Saluton.
Here's the run:
\terri
java -cp . claire.andrea.Saluton
"Hello World".
To sum it up, the package name much match the underlying directory structure.
The file (if it references a package) must live inside the directory stucture it is refering. If I compile Saluton.java in /terri with package claire.andrea I have not found a way to run it, it does compile fine.
Also, the filename for the class must match the public class in that file.
To run, package.Class. In general, packages are not capitalized and Classes are.

You have to put -d directory Options..because
Set the destination directory for class files. If a class is part of a
package,
javac puts the class file in a subdirectory reflecting the package name,
creating directories as needed. For example, if you specify -d c:\myclasses
and the class is called com.mypackage.MyClass, then the class file is called
c:\myclasses\com\mypackage\MyClass.class.

App2 needs to be in the java/java/package1 directory. In java, the package name and the directory for the source code must match. Did you not get a compilation error?

Check what is your classpath value by below command in command prompt
echo %CLASSPATH%
check where your class is getting created.
to compile a java source program you need to check the path you are giving , whether java file is available there or not.

Related

Java Class name with _ - NoClassDefFoundError with "wrong name" [duplicate]

I have a problem while trying executing my java application.
Whenever I try to execute the program through the command
java ProgAudioJ
I get this error:
Exception in thread "main"
java.lang.NoClassDefFoundError: ProgAudioJ (wrong name: es_2011/ProgAudioJ)
at java.lang.ClassLoader.defineClass1(NativeMethod)
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(NativeMethod)
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: ProgAudioJ. Program will exit.
If I remove from my code:
package es_2011;
Everything works perfectly. How do I solve the problem?
Because I found these answers unclear, here is what you need to do.
First, if you package your code (IE your classes have the package keyword at the top) the compiled classes have to be in a directory with the same name as your package declaration in code. After you have compiled your classes, you need to move up a directory when you exectute the java command, and you include the name of the package. For example, if your code exists in /myFolder/myPackage/ , and your class starts with package myPackage (note that the directory and the package are the same name), then you would do the following (linux / osx):
cd /myFolder/myPackage
javac MyClass.java
cd ..
java myPackage.MyClass
Edit - A late edit to clarify something I see people get confused on. In the example above, the package is only one deep, meaning its just myPackage. If you code has a larger package, like
package com.somedomain.someproject;
you will need to execute the java command from the directory which contains the root directory for that package. For example if your compiled code is in myCode/com/somedomain/someproject/MyMainClass.class, then you will execute the java command from the myCode folder, like this (Again, take special note that the directory structure is the same as the package declaration):
cd /myCode
java com.somedomain.someproject.MyMainClass
Try using:
java es_2011.ProgAudioJ
(instead of java ProgAudioJ).
I'm making some assumptions here about your current working directory and your CLASSPATH. If you can provide information about the command you're running (e.g. what directory you're in, where the class file is located, etc.), we can help you more efficiently.
Try this (compile and run):
dir
2011-02-10 00:30 <DIR> .
2011-02-10 00:30 <DIR> ..
2011-02-10 00:27 58 es_2011
javac es_2011/ProgAudioJ
java es_2011.ProgAudioJ
It's quite clearly stated there:
java.lang.NoClassDefFoundError: ProgAudioJ (wrong name: es_2011/ProgAudioJ)
If you want to put a class in a package(*), then the source code must be placed in a corresponding directory, e.g.,
src/Main.java <- root package (no declaration)
src/es_2011/ProgAudioJ.java <- package es_2011;
(*) You should do it always, except for tiny throw-away stuff and possibly for the main class.
Try this,
Compile your class using below command
$ javac ProgAudioJ.java -d .
Run your application by command
$ java es_2011.ProgAudioJ
The reason that it works when you remove
package es_2011
is that you are changing how the compiler packages up, and effectively locates, the file.
I had the same problem - and the error message wrong name: does indeed point you to the answer. You are using the wrong name "ProgAudioJ" in order to run the .class file.
It has been packaged up as
es_2011/ProgAudioJ
In order to run it - you have to either move up a directory:
If you are here: (Windows)
src\es_2011\
move to
src\
Then run the line:
java es_2011.ProgAudioJ
This tells the compiler to look for the ProgAudioJ - which resides in the es_2011 package. For a standard installation, this will be based on folders - so it will look for the es_2011 folder first, and then the name of the .class file that you want to run (ProgAudio).

Run Eclipse project from command line

I am having two problems regarding compiling and running an Eclipse java project from command line. This works fine when I am just running from the eclipse IDE. I tried googling but couldn't really get the thing working. Any help is much appreciated.
Problem 1: When I try to compile from a location different from the directory where the .java file is, it throws the error "cannot read: myfile.java". But if I migrate to this directory then it compiles.
The command that I was giving is (when in some other directory):
javac -cp C:\ABC\src\XYZ myfile.java
The command that I was giving when in XYZ directory:
javac myfile.java
This generated two .class files myfile.class and Testing_Thread.class(I guess this because I have a thread in my code)
Problem 2: After I have compiled by going to its directory, when I try to run the program, I get the error "Exception in thread "main" java.lang.NoClassDefFoundError: myfile (wrong name: XYZ/myfile.java)" even when I am trying to run from the XYZ directory. I get the same error when I try to run from some other place also.
The command that I was giving when in XYZ directory:
java myfile
The command that I was giving when in some other place:
java -cp C:\ABC\src\XYZ myfile
I am also attaching a hierarchy of my directory structure if it is of any help:
These examples assume the following source structure:
C:\temp\compile-test\src\a\b\c\D.java
Where D.java is:
package a.b.c;
public class D { }
The first problem, cannot read: myfile.java, is because it is not correct to use the cp command line option to point to your source code.
C:\temp\compile-test\src>javac -cp c:\temp\compile-test\src\a\b\c D.java
javac: file not found: D.java
Usage: javac <options> <source files>
use -help for a list of possible options
This should instead be the following, where javac is run from your source folder, and we can use relative paths to the source files (NOTE - javac is run from the source folder here):
C:\temp\compile-test\src>javac a\b\c\D.java
Or this, where we specify full paths to the source files, and javac can be run from anywhere (NOTE - javac is run from C:\ here):
C:\>javac temp\compile-test\src\a\b\c\D.java
Both of the above options will result in your class files being created in the same folder as the source. I.e.:
C:\temp\compile-test\src\a\b\c\D.class
For the second problem, if you try and run a class that has a package name from 'inside' the package, this will result in the name being wrong (NOTE - java being run from 'inside' the package here):
C:\temp\compile-test\src\a\b\c>java D
Exception in thread "main" java.lang.NoClassDefFoundError: D (wrong name: a/b/c/D)
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: D. Program will exit.
To run the D class, you should be at the package 'root', and supply the Fully Qualified Class Name. I.e.:
C:\temp\compile-test\src>java a.b.c.D
Exception in thread "main" java.lang.NoSuchMethodError: main
Note I get an exception as the D class doesn't have a main method, and so cannot be run. To fix, we add a main method:
package a.b.c;
public class D {
public static void main(String[] args) {
System.out.println("main");
}
}
and re-run:
C:\temp\compile-test\src>java a.b.c.D
main

Java - running my prog from terminal and getting the following error messages (w/ NoClassDefFoundError) [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
NoClassDefFoundError , Java
> java foo/boo/Prog
Exception in thread "main" java.lang.NoClassDefFoundError: foo/boo/Prog
Caused by: java.lang.ClassNotFoundException: foo.boo.Prog
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:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: foo/boo/Prog. Program will exit.
I'm really lost. I have a directory foo/boo/ and in that I have Prog.class along with some other dot-class files. foo is a subdirectory of the current directory where I run the command from. I compiled it fine, and in my foo/boo/ directory I've checked to make sure that there is indeed a "Prog.class" along with all the other dot-class files I need. There is a main method in my Prog class, and I'm pretty sure this problem has nothing to do with my source code (although it could of course) because I was able to run Prog fine in eclipse, just not from my terminal (ssh-ing onto another machine).
Could someone try to decipher what all of that jumble might mean? I don't really understand. Thank you very much.
$ java -h
Usage: java [-options] class [args...]
(to execute a class)
You are trying to specify the filesystem path to your class file, this is not possible. You need to specify the classpath correctly, so the class can be found by the classloader.
The classpath is a set of paths, where the java classloader looks for the classes to load. So specify the correct folders after the -cp parameter and it will be fine.
I'm probably misunderstanding (and don't have enough to just comment on questions) but are you saying you have a Prog directory, with a Prog.class in there? Wouldn't that make it foo.boo.Prog.Prog ?
Start from outside of foo/boo/Prog, i.e. having current directory being the parent of foo and run as #grtt1 said.
SAMPLE THAT WORKS
suzan#nebulla:~/Test_Java_01$ ls
foo
suzan#nebulla:~/Test_Java_01$ ls foo
boo
suzan#nebulla:~/Test_Java_01$ ls foo/boo
Prog.class Prog.java
suzan#nebulla:~/Test_Java_01$ cat foo/boo/Prog.java
package foo.boo;
public class Prog {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
suzan#nebulla:~/Test_Java_01$ java foo.boo.Prog
Hello world

Understanding JARs and Packages in Java

I'm trying to understand how jars and packages work in Java. So to do this, I created a simple test JAR and am trying to use a class contained in that jar. Simple enough, but it is giving me errors like "class not found". Here's the setup:
1) I have a file called MyHelloWorld.java, which will be packaged in a JAR:
package com.mytest;
public class MyHelloWorld {
public String getHello() {
return "Hello";
}
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
2) I have another file called 'HelloHello.java' which uses the function getHello() in com.mytest.MyHelloWorld
import com.mytest.*;
public class HelloHello {
public static void main (String[] args) {
MyHelloWorld hello = new MyHelloWorld();
System.out.println(hello.getHello());
}
}
3) To package the MyHelloWorld class inside a JAR, I created the folders com/mytest in the current directory, and moved MyHelloWorld.java to that folder
4) I compiled MyHelloWorld.java in that folder using javac MyHelloWorld.java
5) I ran jar -cf myhello.jar ./com/mytest/*.class from the root folder to create the JAR file (as described in http://www.javacoffeebreak.com/faq/faq0028.html)
6) I copied HelloHello.java and myhello.jar to a new folder with nothing else in it, to test this setup
7) javac -cp ./*.jar HelloHello.java [succeeds]
8) java -cp ./*.jar HelloHello [FAILS] (I also tried just `java HelloWorld', which failed too, with a different error message)
This last statement fails with the message:
$java -cp ./*.jar HelloHello
Exception in thread "main" java.lang.NoClassDefFoundError: HelloHello
Caused by: java.lang.ClassNotFoundException: HelloHello
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:315)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398)
Any idea why it's failing? Any insights you can provide on why it works this way, and how package names are defined inside a JAR etc. would also be appreciated!
I believe it is looking in the jar for your HelloHello class. You probably need the current folder on the classpath too.
java -cp .:myhello.jar HelloHello
You should use:
java -cp .:./* HelloHello
java and javac treat -cp argument a bit differently. With java the * in cp will automatically load all the jars it finds in the given location.
Also, the colon : is the separator between different classpath elements.
Make sure if HelloHello.class is in appropriate directories structure (com/mytest) than change your 8th step:
8) java com.mytest.HelloHello //or java -cp .;*.jar com.mytest.HelloHello
well, java HelloHello works too

Using a jar in a Java project?

I'm trying to use the public methods/classed from a project provided as a jar file (called Hello.jar for instance) wrapped in a package called hello.
package hello;
public class Hello
{
public static void main(String[] args)
{
coucou();
}
public static void coucou()
{
System.out.println("Hello there");
}
}
In a separate project called Tool, I want to be able to call the method Hello.coucou() so I wrote something like this:
import hello.*;
public class Tool
{
public static void main(String[] args)
{
System.out.println("main program running");
Hello.coucou();
}
}
and I compiled Tool.java with the following command (under linux):
$ javac Tool.java -classpath .:./extern/:
where Hello.jar is located in the folder ./extern
This seems to compile fine but when I launch it (i.e. java Tool), I get this:
main program running
Exception in thread "main" java.lang.NoClassDefFoundError: hello/Hello
at Tool.main(Tool.java:9)
Caused by: java.lang.ClassNotFoundException: hello.Hello
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
... 1 more
I am new to Java (C/C++ background) and I don't understand what I'm doing wrong.
Any ideas?
Cheers
David
Edit: I tried adding Hello.jar to the classpath on the command line, but I still get the same error:
$ javac Tool.java -classpath .:./extern/Hello.jar:
$ java Tool -classpath .:./extern/Hello.jar:
main program running
Exception in thread "main" java.lang.NoClassDefFoundError: hello/Hello
at Tool.main(Tool.java:9)
Caused by: java.lang.ClassNotFoundException: hello.Hello
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
... 1 more
You need the Hello.jar on the classpath when you run as well as when you compile.
Actually the trick was in the order of the arguments in the command line:
Is the -cp (or -classpath) is set last, then it doesn't work
java Tool -cp .:extern/Hello.jar
It has to be first like:
java -cp .:extern/Hello.jar Tool
!!!
Java uses dynamic late binding, so putting the JAR in the classpath during compilation is only necessary to ensure that your code is using the classes from it correctly, but it does not actually embed them into your code as the linker would in C/C++. Thus, you need to set the classpath also when executing the code.
However, this:
$ javac Tool.java -classpath .:./extern/:
should not work either, since JARs need to be put into the classpath directly, not just the directory they live in:
$ javac Tool.java -classpath .:./extern/Hello.jar
Finally, you are placing your code in the default nameless package. This is OK for fooling around, but will cause problems in the long run (for one thing, you cannot import classes FROM the default package anywhere else).
When you run Java you must add the jar file too (adding the directory path only does not work).
See classpath information.
It should be something like this:
java -classpath /java/MyClasses/myclasses.jar utility.myapp.Cool
You need to include the Hello.jar file in the classpath when you launch it too.
java -cp xxx.jar hello where xxx is the jar you want to have in your classpath, if you want multiple jars then separate them using ;
karl

Categories