Novice linux java coder needs help getting progs to run

B

boltar2003

Hi

I'm just starting to teach myself java and as such I've installed the
latest jre1.6 and jdk1.6 for Linux from Suns website into /usr/local. I've
set my PATH to point to /usr/local/jre1.6.0_16/bin, /usr/local/jre1.6.0_16,
/usr/local/jdk1.6.0_16/bin and /usr/local/jdk1.6.0_16/. Also I've set
my CLASSPATH to point to /usr/local/jre1.6.0_16/lib:.

Compiling my test programs works fine, however when I run my simple hello
world program I get the following:

tantallon$ java hello.java
Exception in thread "main" java.lang.NoClassDefFoundError: hello/java
Caused by: java.lang.ClassNotFoundException: hello.java
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.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: hello.java. Program will exit.

Can someone tell me what I need to do to fix this as the answers google
brings up all seem to point to a wrong CLASSPATH but that doesn't seem to
fix this error.

Thanks for any help

B2003
 
B

boltar2003

On Tue, 18 Aug 2009 09:14:36 +0000 (UTC)
tantallon$ java hello.java

Sorry , shouldn't reply to myself but I obviously meant hello.class

tantallon$ java hello.class
Exception in thread "main" java.lang.NoClassDefFoundError: hello/class
Caused by: java.lang.ClassNotFoundException: hello.class
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.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: hello.class. Program will exit.


B2003
 
B

boltar2003

You need to pass java the name of a class, not the name of a file - the
java executable interprets "hello.class" as referring to a class called
"class" in the "hello" namespace (hence the error message). Instead, use:

java hello

Ah christ , it was that simple, works now. I'm an idiot. Thanks!

B2003
 
A

Arved Sandstrom

On Tue, 18 Aug 2009 09:14:36 +0000 (UTC)


Sorry , shouldn't reply to myself but I obviously meant hello.class

tantallon$ java hello.class
Exception in thread "main" java.lang.NoClassDefFoundError: hello/class
Caused by: java.lang.ClassNotFoundException: hello.class
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.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: hello.class. Program will exit.


B2003
Class names should start with an uppercase letter. And as "I V" stated,
drop the ".class" suffix when using the "java" command - some other
tools need this (because they work on Class objects, and "javac" needs
the ".java" suffix), but not "java".

Having said that, what "javac" command successfully compiled the source?

AHS
 
A

Andreas Leitgeb

I'm just starting to teach myself java and as such I've installed the
latest jre1.6 and jdk1.6 for Linux from Suns website into /usr/local. I've
set my PATH to point to /usr/local/jre1.6.0_16/bin, /usr/local/jre1.6.0_16,
/usr/local/jdk1.6.0_16/bin and /usr/local/jdk1.6.0_16/.

As the actual question is solved by now, some extra comment:

There is no point in adding /usr/local/jre1.6.0_16 and
/usr/local/jdk1.6.0_16 to the PATH. Unlike the "bin"-subdirs,
these two directories do not directly contain any programs.
 
B

boltar2003

I don't know about idiot, but there are simple tutorials out
there, and finding and following tutorials *is* a basic skill.

Perhaps if the runtime had returned a more meaningful error I wouldn't
have needed to post in the first place. But thanks for rubbing it in. We all
make silly mistakes so leave off with the patronising replies ok?

B2003
 
B

boltar2003

As the actual question is solved by now, some extra comment:

There is no point in adding /usr/local/jre1.6.0_16 and
/usr/local/jdk1.6.0_16 to the PATH. Unlike the "bin"-subdirs,
these two directories do not directly contain any programs.

True, but some programs I've worked with in the past use $PATH as a starting
point to search through subdirectories for stuff they need.

B2003
 
L

Lew

I've set my PATH to point to /usr/local/jre1.6.0_16/bin,
/usr/local/jre1.6.0_16, /usr/local/jdk1.6.0_16/bin and
/usr/local/jdk1.6.0_16/. Also I've set my CLASSPATH to point to
/usr/local/jre1.6.0_16/lib:.

You should include only one of the bin/ directories in the PATH and neither of
the home directories. You should leave CLASSPATH unset, usually. You should
set JAVA_HOME to one of the home directories. I suggest

export JAVA_HOME=/usr/local/jdk1.6.0_16
PATH=${JAVA_HOME}/bin:${PATH}
#(assuming PATH didn't previously contain that directory)

for bash and the equivalent for other shells.
 
L

Lew

True, but some programs I've worked with in the past use $PATH as a starting
point to search through subdirectories for stuff they need.

That is not what PATH is for. PATH is for directories that directly contain
executables.
 
N

Nigel Wade

Hi

I'm just starting to teach myself java and as such I've installed the
latest jre1.6 and jdk1.6 for Linux from Suns website into /usr/local. I've
set my PATH to point to /usr/local/jre1.6.0_16/bin, /usr/local/jre1.6.0_16,
/usr/local/jdk1.6.0_16/bin and /usr/local/jdk1.6.0_16/. Also I've set
my CLASSPATH to point to /usr/local/jre1.6.0_16/lib:.

Besides the advice given by others, there are a couple of other points worth
noting.

It's not necessary to have both the JRE and the JDK installed. The JDK is a
superset of the JRE (i.e. it includes the JRE). Having both won't hurt, it just
isn't necessary. If you look in /usr/local/jdk1.6.0_16/ you'll see that it has
the jre subdirectory, which contains everything which the JRE does. You also
don't need to set your PATH to point to both the JDK and the JRE, the JDK/bin
directory contains everything you need to both compile and run Java. The
JDK/jre/bin (or JRE/bin) directory contains what you need just to run Java.

The second point is that it is generally unnecessary to set CLASSPATH. I'd say
that, unless it's really is necessary, you are far better off not setting it at
all because it causes more confusion than it alleviates. You can do everything
that CLASSPATH does by specifying the classpath on the java command line with
the -cp argument. Until you get used to how classpaths work you are going to
learn much more by explicitly setting it on the java command line than you are
by forgetting to set CLASSPATH correctly and getting NoClassDefFoundError. Once
you understand classpaths you can use CLASSPATH to save you some typing, but
it's best not to have it set universally at login.

I would second that advice given by Bugbear, online tutorials can be a really
good place to start, and the Sun Tutorial is particularly good. For example,
the tutorial pointed to by Bugbear gives step-by-step instructions on how to
create a Java application on Linux.
 
B

boltar2003

I think he wanted the entire command.

"javac hello.java" -ie with the .java extension - is the only way that
works otherwise:

tantallon$ javac hello
error: Class names, 'hello', are only accepted if annotation processing is explicitly requested
1 error

So it works in the opposite way to the java runtime command line unless you
presumably specify some option.

B2003
 
A

Andreas Leitgeb

True, but some programs I've worked with in the past use $PATH as a starting
point to search through subdirectories for stuff they need.

Interesting...

I haven't seen any such program, but if one existed, as you say, then
it would probably discard any trailing "/bin", anyway, e.g. to find
/usr/local from /usr/local/bin. - Or did they also require you to add
"/usr" and "/usr/local" to your PATH? Then I'd consider them buggy.

Unlike Lew, I do see some merit in that strategy, but if that strategy
was well implemented, then it still shouldn't make it necessary to add
"/usr/local/jdk1.6.0_16" to the PATH when "/usr/local/jdk1.6.0_16/bin"
was already there.

Were those programs publically known ones, or internal/private hacks?
 
M

markspace

So it works in the opposite way to the java runtime command line unless you
presumably specify some option.

No, I think it just works opposite. I think (but I'm not 100% sure)
that file names aren't required to have a .java extension, hence the
need to specify the whole name.

Alternately it works the same -- with out an extension, the Java command
lines assumes a .class file. The second error is telling you that
"hello" is valid. You can post-process .class files for annotations, so
again, for compiling source text you must specify the .java extension.

Incidentally, we asked about the command line because something like this:

javac -s mystuff/src hello.java

The resulting .class file would have been in a different location
entirely, and you'd need a different java command to execute it.

java -cp mystuff/src hello
 
L

Lew

"javac hello.java" -ie with the .java extension - is the only way that

Class names should begin with an upper-case letter.
works otherwise:

tantallon$ javac hello
error: Class names, 'hello', are only accepted if annotation processing is explicitly requested
1 error

So it works in the opposite way to the java runtime command line unless you
presumably specify some option.

The two commands have very different purposes; there isn't an
"opposite" way here. The purpose of the "javac" command is to
manipulate files; the purpose of the "java" command is to manipulate
classes.

So when you specify "javac Hello" you are telling the compiler to
compile a file named "hello". It doesn't make sense to specify
classes to the compiler because it's the compiler's job to convert
files into bytecode.

When you specify "java Hello" you are telling the JVM to execute the
standard 'main()' method in a class called 'Hello' in the default
package. It doesn't make sense to tell the runtime to execute a file
because its job is to run a method in a class. That the class
bytecode lives in a file is an implementation detail and not central
to the purpose.

There are no options to subvert the purposes of these utilities. The
point of the CLASSPATH envar and the command-line "-classpath" ("-cp")
options is to inform the "java" tool where to find classes.

It's a little tricky, and it gave me pause when I started out in Java
myself. I found it useful to remember that "javac" manipulates files
and "java" manipulates classes.

When you start using packages, which you should as soon as possible,
that means that "javac" looks at files in directories, e.g., "javac
package/Foo.java", and "java" looks at classes in packages, "java
package.Foo".

This is covered in the tutorials and other Java learning materials.
 
L

Lew

Andreas said:
Unlike Lew, I do see some merit in that strategy, but if that strategy
was well implemented, then it still shouldn't make it necessary to add
"/usr/local/jdk1.6.0_16" to the PATH when "/usr/local/jdk1.6.0_16/bin"
was already there.

It isn't a question of "merit" but of the documented purpose of the
envar. I find it strange to cast that in terms of "merit". All I did
was report on what the variable is for, without endorsement or
critique.

<http://www.gnu.org/software/bash/manual/bashref.html#Command-Search-
and-Execution>
If the name is neither a shell function nor a builtin, and contains no slashes,
Bash searches each element of $PATH for a directory containing an executable file
by that name.

Windows is similar.
 
L

Lew

markspace said:
Incidentally, we asked about the command line because something like this:

javac -s mystuff/src hello.java

The resulting .class file would have been in a different location
entirely, and you'd need a different java command to execute it.

java -cp mystuff/src hello

Here's one standard layout and associated command lines for a prototypic "foo"
project:

${PROJECTS}/foo/
|- build/classes/
|- src/com/lewscanon/foo/
|- Foo.java

Commands:

$ cd ${PROJECTS}/foo/

$ javac -d build/classes/ src/com/lewscanon/foo/Foo.java

$ ls build/classes/com/lewscanon/foo/
Foo.class

$ java -cp build/classes/ com.lewscanon.foo.Foo
 
B

boltar2003

or better still
java Hello

Class names should start with a capital letter as should the
Hello.java file it lives in.

Why? It looks daft and is more hassle to type on systems which are case
sensitive (ie almost all of them except Windows).

B2003
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top