English 中文(简体)
Java Library and Class Path Problems
原标题:

Quick personal background: I was hired a few months ago as the sole .NET developer (C#) by a company whose other devs are all php devs. A week into the job I was told they wanted to switch to Java instead of doing .NET. Not an ideal situation, but I m trying to make it work.

I don t think I understand the relation between a project s library and the class path. I am using NetBeans 6.7.1 for development. My current project is to create an application that will update multiple merchant sources (eBay, Amazon, etc). I created a Class Library project that handles scheduling of these updates. We ll call it Update.

I am in the process of creating Class Library projects for the various sources (e.g. eBay). I added the ebay project to the Update project as a Library. In the IDE there is a box that says "Build Projects on Classpath" which is checked.

Finally, right now I have a little console app that has the Update project referenced as a Library (so the ebay project is now 2 libraries deep) in the same manner. It works with code in the Update project.

This works OK until I get to instantiating a class (from the Update project via the console app) that is in the ebay project. At that point I get a

Exception in thread "main"
java.lang.NoClassDefFoundError

which is

 Caused by: java.lang.ClassNotFoundException
  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:307)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
  at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)

These projects all build fine but this runtime exception is killing me. I don t know if I really understand what adding a Library to a project does and if there is something more I need to do to make the class accessible. I m used to being able to add a reference to a DLL and being good to go. I don t understand why I don t get any compiler errors or build errors but I get run time errors about accessibility. I m guessing the classpath is a missing piece that I don t understand too well, although I suppose it s possible this problem has to do with something else entirely.

最佳回答

The solution I have come up with for now:

I expected the references from nested libraries to "bubble up". This apparently doesn t work for classpaths. My structure was basically:

A has reference to B has reference to C

When I ran A it worked fine until it got to something in C. What I did was give A a direct reference to C by adding it as a library to the project. From some quick Google searches it looks like this pretty much IS how you add a classpath to a project in NetBeans.

It seems a bit messy to me and maybe there is a better way to do that, but it has fixed my problems for now. Thanks to everyone who answered - while no one precisely solved my particular problem (you guys got me about 95% of the way there though) they verified my thoughts and enabled me to figure out that last little bit to get it going.

问题回答

I highly recommend picking up Core Java, volumes 1 and 2. They are must reads for Java developers that want to understand the internals of the language such as the ClassLoader. At the very least, read up on class loading.

To answer your question, the Update project should be generating .class files or jar. You need to have the location of either the class files or the jar in your classpath for the project that you are referencing them from. Depending on your IDE, having a reference to the project might only give you access to the source, for compiling.

You need to separate Java concepts from IDE-specific concepts. I recommend going through a simple java tutorial using a text editor and command shell before jumping into NetBeans.

Library and Project are NetBeans specific terms. I m not a NetBeans user, so I won t try to guess what they are although I have some guesses, but I will say that their configuration will most likely affect compile-time environment.

A Classpath is a core java concept. You must provide the paths to all your classes (or jars that contain those classes) to the java command at runtime in order for it to be able to load those classes. (You also need to do the same to the javac command at compile-time for the classes that you re referencing but not compiling at the moment).

Any time you see java.lang.ClassNotFoundException, it means that some class that was present on the classpath when you compiled your code is missing from the classpath when you launched the runtime.

In Java, unlike C#, you need to explicitly add the class paths to project. I use eclipse and I had to do this get some of the referenced jars loaded.

Exception in thread "main"
java.lang.NoClassDefFoundError

The classname is missing in the error message, but let s suppose that it is the class itself for which you wanted to execute the main method. In that case it just means that Java cannot find the particular class in the runtime classpath.

To fix this you need to cd to the root of the package where the class is located in and then re-execute the java command as follows:

java -cp . com.example.MainClass

Here the -cp argument specifies the classpath. It has only a value of . which means that the current working directory should be taken into the classpath (which is usually the default case, but better safe than nothing).

Alternatively you can specify its full path in the -cp argument, so that you can execute it from everywhere, e.g.:

java -cp /path/to/package/root com.example.MainClass

Another alternative which is most seen in tutorials for starters but is usually not been used by professionals is defining an %CLASSPATH% environment variable wherein you put exactly that value what you d like to use in the -cp argument. Then the java command will lookup it (as long as you do not use one of the -cp, -classpath or -jar arguments).

If typing the long commands get bored you can use a batch or shell file for this so that you can manage it easily.

If you for instance have a JAR file or another root package folder with classes which you d like to use in your program, then you need to append them to the classpath. When on Windows, the separator is the semicolon ; and when on Linux the separator is :. Further on when a path contains spaces, you need to quote the particular path. Here s a Windows example:

java -cp .;/path/to/package/root;"/spacy path/to/file.jar" com.example.MainClass

Hope this helps.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签