sorry in advance if I don't give enough information or if I'm unclear about anything, this is my first foray into using .bat and .config files.
I'm using a piece of academic software and am trying to add and run my own components. the system uses a config file to launch a list of components (classes) required for the system using code like this:
semaine.components = \
eu.semaine.examples.swimmer.SwimmerDisplay| \
the system runs correctly and the specified components are initialised.
I add my own component to the list of existing components using the following code:
eu.semaine.examples.TestPackage.MyTest| \
however I get the following error:
java.lang.NoClassDefFoundError:eu/semaine/examples/TestPackage/MyTest (wrong name: TestPackage/MyTest)
I've had a look around and it seems to me that I'm not doing any of the things which usually cause this error, e.g. my class name matches the file name it is stored in (public class MyTest is stored in MyTest.java), MyTest is in the package TestPackage and the folder in the file structure is also named TestPackage.
any ideas or advice would be greatly appreciated.
You have asked for
eu.semaine.examples.TestPackage.MyTest
but say that you have placed the file in a directory called TestPackage.
Look carefully at the classpath specified in your batch file. My guess is that you have a directory hierarchy like this for the initial clash, rooted at that specified classpath
eu
semaine
examples
swimmer
SwimmerDisplay
in saying eu.semaine.examples.TestPackage.MyTest you are saying that the package will be "eu.semaine.examples.TestPackage" and the directory hierarchy will now be
eu
semaine
examples
swimmer
SwimmerDisplay.class
TestPackage
MyTest.class
I think you intend instead:
eu
semaine
examples
swimmer
SwimmerDisplay.class
TestPackage
MyTest.class
and to say that the class is just
TestPackage.MyTest
not
eu.semaine.examples.TestPackage.MyTest
[In passing I agree that normal convention is not to capitalise package names, but I don't beleive that Java infers and semantic from the capitalisation.]
It sounds like your class is not in the application's classpath when it's started. You mention .bat files. If that's how you start the application, then it should contain a section where the classpath is assembled. It must contain the parent folder of the TestPackage folder so that the JVM knows where to find your class file.
Naming convention states that package names must be all lower case, see http://download.oracle.com/javase/tutorial/java/package/namingpkgs.html.
I guess the jvm thinks that TestPackage is a class and MyTest is an inner class.
Related
There is a class a.b.c.Hello of which I would just get the Hello.class file delivered. I would like to run using something like:
java Hello
//or
java a.b.c.Hello
This leads me to a NoClassDefFoundError. Normally I'd have the a/b/c dirs with the class insdie and I'd add them to the -classpath option, but:
Is there a way of running a class in a package like this without having to put it inside a/b/c to match the package name?
All solutions I've found state the directory structure has to match the package naming, but I'd like to run the .class file directly from the folder where it is without recreating the folder structure
Is there a way of running a class in a package like this without having to put it inside a/b/c to match the package name?
Yes: By using a jar. Put the .class file in the jar (with the correct path), and then:
java -cp TheJarFile.jar a.b.c.Hello
This is, of course, very much like putting it in an a/b/c directory; it's just that the directory is in the jar, not the file system.
The packages do not just structure your classes (in folders), they also create a namespace. While the simple class name is Hello, the real class name is a.b.c.Hello.
That's because class names might repeat frequently (in different libs, f.e), but must be addressable on the other hand. For example: 'User', 'Logger', 'List', 'Date'.
Its not recommended, but you can put your class in the default package, too. Just remove the 'package ...' line.
I think I am failing to understand java package structure, it seemed redundant to me that java files have a package declaration within, and then are also required to be present in a directory that matches the package name. For example, if I have a MyClass.java file:
package com.example;
public class MyClass {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
Then I would be required to have this file located in com/example, relative to the base directory, and I would execute java com.example.MyClass from the base directory to run it.
Why wouldn't the compiler be able to infer the package name by looking at the directory structure? For example, if I compiled the file from the base directory javac com\example\MyClass.java, I am not understanding why the MyClass.java wouldn't implicity belong to the com.example package.
I understand there is a default package, but it still seems that the package declaration in the source file is redundant information?
As you (implicitly) acknowledged, you are not required to declare the name of a package in the case of the default package. Let us put that quibble aside ...
The reason for this seeming redundancy is that without a package declaration, the meaning of Java1 source code would be ambiguous. For example, a source file whose pathname was "/home/steve/project/src/com/example/Main.java" could have 7 different fully qualified names, depending on how you compiled the code. Most likely, only one of those will be the "correct" one. But you wouldn't be able to tell which FQN is correct by looking at (just) the one source file.
It should also be noted that the Java language specification does not require you to organize the source code tree according to the packages. That is a requirement of a (large) family of Java compilers, but a conformant compiler could be written that did not require this. For example:
The source code could be held in a database.
The source code could be held in a file tree with random file names2.
In such eventualities, the package declaration would not be duplicative of file pathnames, or (necessarily) of anything. However, unless there was some redundancy, finding the correct source "file" for a class would be expensive for the compiler ... and problematic for the programmer.
Considerations like the above are the practical reason that most Java tool chains rely on file tree structure to locate source and compiled classes.
1 - By this, I mean hypothetical dialect of Java which didn't require package declarations.
2 - The compiler would need to scan the file tree to find all Java files, and parse them to work out which file defined which class. Possible, but not very practical.
Turn the question on its head:
Assume that the package statement is the important thing - It represents the namespace of the class and belongs in the class file.
So now the question is - Why do classes have to be in folders that match their package?
The answer is that it makes finding them much easier - it is just a good way to organize them.
Does that help?
You have to keep in mind that packages do not just indicate the folder structure. The folder structure is the convention Java adopted to match the package names, just like the convention that the class name must match the filename.
A package is required to disambiguate a class from other classes with the same name. For instance java.util.Date is different from java.sql.Date.
The package also gives access to methods or members which are package-private, to other classes in the same package.
You have to see it the other way round. The class has all the information about itself, the class name and the package name. Then when the program needs it, and the class is not loaded yet, the JVM knows where to look for it by looking at the folder structure that matches the package name and the class with the filename matching its class name.
In fact there's no such obligation at all.
Oracle JDKs javac (and I believe most other implementations too) will happily compile your HelloWorld class, no matter what directory it is in and what package you declare in the source file.
Where the directory structure comes into the picture is when you compile multiple source files that refer to each other. At this point the compiler must be able to look them up somehow. But all it has in the source code is the fully qualified name of the referred class (which may not even have been compiled yet).
At runtime the story is similar: when a class needs to be loaded, its fully qualified name is the starting point. Now the class loader's job is to find a .class file (or an entry in a ZIP file, or any other imaginable source) based on the FQN alone, and again the simplest thing in a hierarchical file system is to translate the package name into a directory structure.
The only difference is that at runtime your "standalone" class too has to be loaded by the VM, therefore it needs to be looked up, therefore it should be in the correct folder structure (because that's how the bootstrap class loader works).
So i have been working on my Project1 and For some reason i cant figure out why It wont run. I get the Error "Could not find the main class". What am i doing wrong?
My code is:
https://gist.github.com/anonymous/6604f427cc9d17391478
I'm not sure how to post all the code properly with out making it super confusing (I tried to figure it out earlier) But let me know if i can help!
Is there something wrong with my code? Or do i need to compile it in a certain way?
if your using eclipse, goto to run configurations, select:
Project: my Project1
Main Class: assignment1.Assignment1_test
this will work for sure :)
Let's say you have a folder/package assignment1 somewhere on your file system inside which you have your Assignment1_test and Fraction class.Refer the screenshot above to compile and run your code. :)
You have it in a package named assignment1. This means it is in a folder named assignment1. After compiling, go up to the folder that contains assignment1 then run java assignment1.Assignment1_test from there.
java expects a fully-qualified class name (the name of the class including the package). It also expects that the class is in your classpath (. is implicitly added). Packages are tied directly to the directory structure.
Combining that all together, since the full-qualified name assignment1.Assigment1_test must be specified to java, and since the package structure is the directory structure, then the class is expected to be in assignment1\ relative to the current directory and therefore you must be in the directory that contains assignment1 to execute it (unless it is somewhere else in your classpath, which, given your situation, I'm guessing is not the case).
I am trying to run the java prog I've built, but I want to run it from a specific directory. When specifying the relative path to the class file I want to run, that path contains a directory with a period in it, and it seems to be tripping java up; So for example I try to run:
java -classpath myPath/myPath-1.2.3/myLongPath myPath/myPath-1.2.3/myLongPath/myProg
Java errors out saying that it cannot find the class (NoClassDefFoundError); This makes sense because I see that java is looking in different directory than the one I specified; It is looking in:
myPath/myPath-1/2/3/myLongPath
instead of:
myPath/myPath-1.2.3/myLongPath
Try as I might, I cannot figure out how to specify to java.exe that the directory I want it to look in contains periods. I tried \ escaping the periods, but that doesn't help. Anyone run into this problem before? btw, I am running on linux within gnome terminal. Thanks for any help.
The final parameter in the call to java is the name of the class to run. This is not a file name, but a class name. It includes the full package name (unless the class is in the default package), separated by dots (not slashes). Neither the classname nor any package name can include dots. The folder that represent the path to the package must not be included in the directories included in the classpath (only the top directory for the class folder should be there).
In your case, that seems to be just myProg, but to make sure, what is the class name (including package name) of the class with the main method?
Example:
If I have a class mypackage.mysubpackage.MainClass, and the class file is in /home/me/project/1.3/build/mypackage/mysubpackage/MainClass.class, then the command to run the class would be java -cp /home/me/project/1.3/build mypackage.mysubpackage.MainClass.
Java uses the period as the package component separator, so it simply cannot appear in class names. Since class names are tied to directory structures, it cannot appear in directory names used in class paths either, and no amount of escaping will help you there. (It would have been better to use the directory separator itself as the package component separator, but they differ between operating systems, and Java wanted to be OS independent. This is one of the prices to be paid for that.)
I'm trying to figure out how organize source and class files working with packages. I found a very useful tutorial. But I still have some questions.
As far as I understood it is a good practice to have an isomorphism between name of packages and name of the directories where elements of a package are stored. For example if I have a package named aaa.bbb.ccc which contains class ddd it is a good practice to have a class file called "ddd.class" and located in "$CLASSPATH/aaa/bbb/ccc/". Did I get it right?
If it is the case, will Java compiler put *.class files into the correct directory automatically?
I was not able to get this behavior. I set the $CLASSPATH variable to "/home/myname/java/classes". I executed javac KeyEventDemo.java which contains package events;. I expected that javac will create a subdirectory events under /home/myname/java/classes and put the KeyEventDemo.class in this subdirectory.
It did not happen. I tried to help to javac and created "events" subdirectory by myself. I used javac again but it does not want to put class files under "/home/myname/java/classes/events". What am I doing wrong?
You need to use the -d option to specify where you want the .class files to end up. Just specify the base directory; javac will create any directories necessary to correspond to the right package.
Example (based on your question):
javac -d ~/java/classes KeyEventDemo.java
For example if I have a package named
"aaa.bbb.ccc" which contains class
"ddd" it is a good practice to have a
class file called "ddd.class" and
located in "$CLASSPATH/aaa/bbb/ccc/".
Did I get it right?
That's not "good practice" - this is how the Sun JDK expects things to be. Otherwise, it will not work. Theoretically, other Java implementations could work differently, but I don't know any that do.
If it is the case, will Java compiler
put *.class file into a correct
directory automatically?
Yes
What am I doing wrong?
The source code must also already follow this structure, i.e. KeyEventDemo.java must reside in a subdirectory named "events". Then you do "javac events/KeyEventDemo.java", and it should work.
It is not only good practice but a must in most cases.
consider a Java class named:
com.example.Hello
If you store it on the filesystem, it has to got to
/path/to/my/classes/com/example/Hello.java
The compiler (or at least the vast majority) will create the class file at
/path/to/my/classes/com/example/Hello.class
Personally I would not use the CLASSPATH variable to set the path but the -cp option on java. A call to the above "application" could be done with:
java -cp /path/to/my/classes com.example.Hello