package in .java file makes class file unuseable - java

It's been too long since I've last done Java, and I can't remember why the following happens:
Given this file, created by a standard Maven project, as can be seen here: Maven Tutorial
package com.mycompany.app;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
Compiling this, not even with Maven but with the standard javac executable, will generate a class file without errors. Try to run the class file, and you get this error:
Exception in thread "main" java.lang.NoClassDefFoundError: App (wrong name: com/mycompany/app/App)
Remove the package command, compile again and it runs just fine. Why is this? I'm running JDK 1.6.0_21 btw.

One thing you must do after creating a package for the class is to create nested subdirectories to represent package hierachy of the class. In your case the package name is "com.mycompany.app" so the App.class (compiled App.java file) should reside in "com/mycompany/app" sub-directory. It doesn't matter where the source file is residing though. For example, I have copied your file and did the following:
$ ls
App.java
$ javac App.java
$ ls
App.class App.java
$ mkdir -p com/mycompany/app
$ mv App.class com/mycompany/app/
$ java com.mycompany.app.App
Hello World!
$
Please read Wikipedia page about Java Packages for more information. You can also take a look at these links:
The Java packages tutorial
Java packages tutorial
Oracle's notes on packages
Good luck!

When you attempt to execute your program, it will look for the class file using the path specified in the package. So, when you have the package statement in the file, your class file must be in the com/mycompany/app/ directory (relative to what directory you're attempting to run it from); if it can't find it, you get that exception.
Thus, when you remove that package statement, the JVM will look for it in current directory, which is why it works (because you're executing java App in the same directory in which the App.java and App.class files exist).

You need to add the com/mycompany/app folder to your Java CLASSPATH . If I remember well, you can also do it from the cmdline using the parameter "-cp".

This is because in Java filesystem files map to classes (e.g. each public class must be in a separate eponymous file) and packages map to directories.
So if you have a class which is in the com.mycompany.app package it must be in com/mycompany/app directory relative to the classpath.
In your case you should have an output directory, say and the you should have the class in /com/mycompany/app/App.java. Then you build it, running javac from and giving com/mycompany/app/App.java as parameter, instead of com/mycompany/app/App.java.
Running the class works in an analogical way, but you give the fully-qualified-name of the class, instead of the directory path.

Related

Compiling and running a java program with complex file structure from the commandline

Trying to compile and run my java program from the commandline that is set up a bit weird. The file structure is as follows:
[ROOT]/
|
|____libs/
| |____myExtraJar.jar
|
|____src/
|____main/
|____com/
|____example/
|____myClass.java
The package is defined at the top of the java file as
package com.example;
I am able to compile the program fine (I think) while in the root folder, using
javac -classpath "/libs/myExtraJar.jar" src/main/com/example/*.java
I don't get any compilation errors (such the ones that occur if I leave off the classpath) and I can see that .class files are being created in the com/example/ folder. However, I can't find any way to run the compiled program. Running
java src/main/com/example/myClass
results in the message
Error: Could not find or load main class src.main.com.example.myClass
Any help would be appreciated.
You need to specify the classpath when you run it, and you also need to use the fully-qualified classname. Like,
java -cp "libs/myExtraJar.jar:src/main" com.example.myClass
Elliot is right. More precisely, you need to add the build directory to your classpath. It is the directory containing your *.class files, and is sometimes named target/.
$ java -cp "target:lib/myExtraJar.jar" com.example.myClass
Moreover, src/main/com/example/myClass should be com.example.myClass, which is the fully-qualified class name. See http://www.manpagez.com/man/1/java/ for details of the java command.

Importing my own classes when compiling and running Java file on Windows powershell

I am working on a Java project where there is a directory Project which has two sub-directories(GUI and Logic)
Relevant classes:
frame.java(GUI package)
logic.java(Logic package)
The main class is in the GUI package and it imports a file which is in the 'Logic' package.
On trying the below command and running the file, I encounter an `NoClassDefFoundError'.
javac -sourcepath [path to Project] [file containing the import]
I finally could compile it. All the directories and package names were, right, what I needed to do was to use the following command from my root directory:
javac src/gui/*.java
and then, to run:
java -cp ./src gui.Gui
Thanks for the ones who tried to help!
If I right understand your directory structure is like
.\source
.\source\GUI
.\source\GUI\frame.java
.\source\Logic
.\source\Logic\logic.java
Then this will not work, as the direcotry names should be named like the package names. Change the structure and the class names as
.\source\gui
.\source\gui\Frame.java
.\source\logic
.\source\logic\Logic.java
Assuming the import statements and the class names inside the file are correctly amended you can compile it with
javac -sourcepath source source\gui\Frame.java

JVM Can't Find My Class: java.lang.NoClassDefFoundError

My directory structure looks like this.
PackagesUnit3/com/myname/start/PackagesTest.java
(this class contains my main and the import statement "import com.systems.mui.*;)
PackagesUnit3/com/systems/mui/Test.java
(this class contains the package statement "package com.systems.mui;")
With PackageUnit3 as my base directory I can compile both classes successfully with the statement
"javac com/myname/start/PackagesTest.java"
However I cannot run the code with the command
"java com.myname.start.PackagesTest"
Error: "Exception in thread "main" java.lang.NoClassDefFoundError: com/myname/start/PackagesTest (wrong name: PackagesTest)"
The complier successfully generated .class files for each of the java classes and placed them in the same location as the source files.
According to Horstmann, "Core Java" 9th ed. p. 186, my "java" command syntax ought to work.
I should not have to specify the current directory (".")because I am not using the classpath (-cp) option.
One note: I used the "SUBST R: " command to establish the PackagesUnit3 directory as the base directory. My actual command line looks like R:>
Any suggestions??
Given the exception, it looks like you're missing a package statement:
package com.myname.start;
Your package declaration should match your directory structure, and then the class will be generated with the correct fully-qualified name of com.myname.start.PackageTest.
Either compile in an IDE which will sort things out for you, or compile from the root of your package structure with an optional -d argument to specify the root output directory, e.g.
$ javac -d bin com/myname/start/*.java
$ java -cp bin com.myname.start.PackageTest
I've checked on this, recreated the scenario and you're right... Assuming all classes are public, with correct package declarations, and compiling from the root directory, class Test will compile succesfully since it doesn't references any other classes (or classes from different packages). No -cp option is required
While compiling class PackagesTest, it fails to find class Test. But by adding -cp . , it compiles succesfully.
Once both files are compiled, trying to run PackagesTest' main, will also fail to find class Test. But by adding -cp , it runs smoothly.
By using the option -verbose you can see where is javac (and java) command looking for classes, as it displays the default classpath, which doesn't contains "." (the local directory)

Java can't find main class

I have written the following Java source file (Hello.java):
package com;
public class Hello {
public static void main(String[] args) {
System.out.println("Hello!");
}
}
I save this to C:/tmpjava/Hello.java.
From the command line, I navigate to that directory and run javac Hello.java. Then I run dir:
Hello.class
Hello.java
Then, from the same directory that I just ran javac from, I run java Hello.class and get:
Exception in thread "main" java.lang.NoClassDefFoundError: Hello/class
Caused by: java.lang.ClassNotFoundException: Hello.class
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: Hello.class. Program will exit.
What's going on here?!? How can javac run fine, but not java?
Your class Hello belongs to the package com. So the fully qualified name of your class is com.Hello. When you invoke a program using java on the command-line, you should supply the fully-qualified class name of the class that contains your main method and omit the .class, like so:
java com.Hello
The java program needs this fully-qualified class name to understand which class you are referring to.
But you have another problem. The java program locates packages, sub-packages, and the classes that belong to them using the filesystem. So if you have a package structure like com.Hello, the java program expects to find a class file named Hello.class in a directory named com, like this: com/Hello.class. In fact you can observe this behavior in the Exception that you see; you've incorrectly used Hello.class, which java is interpreting as a package named Hello, and a class named class, and is looking for the directory structure Hello/class:
java.lang.NoClassDefFoundError: Hello/class
But the compiler javac doesn't set up this directory structure by default. See the documentation for javac, but the important bit is this: when you do your compiles, you can specify a destination directory using the -d flag:
-d directory
Set the destination directory for class files. The destination directory must already exist; javac will not create the destination directory. 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.
If -d is not specified, javac puts the class file in the same directory as the source file.
The last bit in bold is the source of much confusion for beginners, and is part of your own problem.
So you have two alternatives:
In your case, it's fine if you supply the current directory as the destination directory, like so (the period . means current directory):
javac -d . Hello.java
If you invoke the compiler like this, it will create the com directory for you, and put your compiled class file in it, the way that the java program expects to find it. Then when you run java as above, from c:\tmpJava, your program should execute.
You could set up your source code using a directory structure that mirrors your package structure: put your source file Hello.java inside a directory called com, in your case: c:\tmpJava\com\Hello.java. Now, from c:\tmpJava you can run your javac compile like this:
javac com\Hello.java
You haven't supplied the -d flag, but that's fine, because you've created the directory structure yourself, and quoting again from the documentation above:
If -d is not specified, javac puts the class file in the same directory as the source file.
Again, when you run java as above, your program should execute.
Note that this second alternative is one that is commonly employed by java programmers: the source code files are organized in a directory structure that mirrors the package structure.
In this explanation we've ignored the concept of the classpath. You'll also need to understand that to write java programs, but in your case of simply compiling a program in the current directory - if you follow one of the two alternatives above when compiling your class - you can get away without setting a classpath because, by default, the java program has the current directory as a classpath. Another quote, this one from the documentation for java:
-cp classpath
Specify a list of directories, JAR archives, and ZIP archives to search for class files. Class path entries are separated by semicolons (;). Specifying -classpath or -cp overrides any setting of the CLASSPATH environment variable.
If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the current directory (.).
Note that when you use an IDE like Eclipse to run your java code, this is mostly handled for you, but you'll still run into classpath issues.
The syntax of the Java command is:
java [classname]
not
java [filename]
Java looks in its classpath for a class of the name you have provided. Usually the classpath includes the current directory, so:
java Hello
... will find Hello.class in the current directory, and run its main() method.
However, if the class is somewhere else (like in a .jar, or somewhere else in the filesystem) you can specify it with the CLASSPATH environment variable, or on the commandline:
java -cp build/classes Hello
java -cp build/jars/myjar.jar Hello
The class should be in C:\tmpjava\com\Hello.class
And you should run from C:\tmpjava: java -cp . com.Hello
When you put a class in a package it defines the file structure of the class. I.e. your class which in package com should be in folder com
Run the following command
java -cp . com.Hello
java -classpath c:\tmpjava com.Hello

Again "wrong name" error when executing java program

With reference to this post
Receiving "wrong name" NoClassDefFoundError when executing a Java program from the command-line
I did not understand how to solve the problem
Actually in my java source code there' s line :
package es_2011;
when I compile the program through JCreator everything works perfectly.
It creates a folder named es_2011 where to put .class files.
Also the executing operation goes smoothly, the program runs ok.
Now I'd like to use the command line only.
So I placed my java file in the directory where javac.exe is but whenever I try to compile I get the same error
The command I use is: javac ProgAudioJ.java
The path (where javac.exe is ) is : C:\Program files\Java\jdk1.6.0_22\bin
Is someone willing to help me understand in terms of exactly tell me what I have to do?
thanks very much...MAX
The setup used for the looks like this (under windows)
C:\classDir -> is the project
C:\classDir\testpackage -> is the only package used (the package "testpackage")
C:\classDir\testpackage\Main.class -> is the class with the main method inside (important: it is the .class and not .java)
The Main.class looks like following:
package testpackage;
public class Main {
public static void main(String[] args) {
System.out.println("Program started! ;-)");
}
}
go with your command prompt to:
c:\classDir> java testpackage.Main
the result:
Program started! ;-)
According to your problems that it starts in your IDE but not from the console:
- checked if you realy use the path to the .class files?
- with the console go to the directory of you .class files, not the project (e.g. in Eclipse it is the bin directory
- enter the full qualified class name (including packages seperated by . -> e.g. testpackage.Main
More infos can be found under:
http://www.oracle.com/technetwork/java/compile-136656.html
Hope it helped
MAX, if the class defines that it's inside the package es_2011, then it should be in a folder with the same name.
So in your case, put the ProgAudioJ.java in the folder es_2011 and then run
javac es_2011\ProgAudioJ.java
latter to run it, you need the command
java es_2011.ProgAudioJ
You should add javac.exe in your path .Edit your path variable and append path to jdk's bin
then put java file in a dir named es_2011 , as the package declaration is es_2011 then compile
c:\es_2011\javac YourJava.java
and now go back to C:
c:\java es_2001.Yourjava
After reading you other Post: "Receiving "wrong name" NoClassDefFoundError when executing a Java program from the command-line" I guess you go to the directory es_2011 where your ProgAudioJ.class file is located and run
java ProgAudioJ
from that folder.
instaend you have to go to the folder above (cd ..) and run
java es_2011.ProgAudioJ
Each package in Java corresponds to a folder on the filesystem. So a package declaration such as com.stackoverflow would mean that the source classes need to be in a folder ./com/stackoverflow. Typically the whole project would have a separate src folder containing com/stackoverflow.
When you compile the Java classes you DO NOT need to put source files in the same directory as javac.exe, you do however need to make sure that javac.exe is in your operating systems PATH variable. This tells the operating system where it should look for executable files when a command is run, on a *nix machine this would usually be /usr/bin or just /bin but on Windows machine the executables normally live within the applications own directories, that is C:\Program Files\something. Assuming that you've installed JDK correctly, the javac.exe should already be in the PATH you can check this by opening the command line and just running javac (just like that). If you get some output then all is well, the system knows where to find javac.exe.
Next you will need to go to your project folder and type javac -d . src/com/stackoverflow/MainSO.java notice that is run from the project folder. This will create a folder called com in your project root and put the compiled classes in com/stackoverflow. The -d flag tells javac where to put the compiled classes, if you leave that out, the compiled classes will be where the sources are.
Then when you want to run the classes you type java com.stackoverflow.MainSO (no .class). Crucially this command will need to be ran in the directory that contains the root of the class hierarchy (that is the com folder containing the compiled classes). You can specify other places for java to look for the classes by providing a classpath to the java command with the -cp flag. By default the classpath will contain the directory the java command was ran in. Should your project have dependencies external .jar files for example you will need to provide every single one of them (with their full filepath) in the classpath (this goes for the compiler as well). The IDEs do this automatically for you.
Hope that helps.

Categories