2009-06-09 3 views
1

Ich versuche, die öffentlichen Methoden/classed aus einem Projekt als JAR-Datei (genannt Hello.jar für Beispiel) in einem Paket namens Hallo verpackt zu verwenden.Verwenden eines Jar in einem Java-Projekt?

package hello; 

public class Hello 
{ 

public static void main(String[] args) 
{ 
    coucou(); 
} 

public static void coucou() 
{ 
    System.out.println("Hello there"); 
} 

} 

In einem separaten Projekt namens Werkzeug, ich will Hello.coucou() die Methode in der Lage sein zu nennen so etwas wie dies schrieb ich:

import hello.*; 

public class Tool 
{ 

public static void main(String[] args) 
{ 
    System.out.println("main program running"); 
    Hello.coucou(); 

} 

} 

und ich Tool.java mit folgendem Befehl kompiliert (unter linux):

$ javac Tool.java -classpath .:./extern/: 

wo Hello.jar in dem Ordner befindet, ./extern

Dies scheint gut zu kompilieren, aber wenn ich es starte (d. H. Java-Tool), bekomme ich diese:

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 

Ich bin neu in Java (C/C++ Hintergrund), und ich verstehe nicht, was ich falsch mache. Irgendwelche Ideen?

Prost David


Edit: I Hello.jar zu dem Classpath auf der Kommandozeile versucht, indem, aber ich immer noch die gleichen Fehler:

$ 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 
+0

Ich würde eher Semikolons als Doppelpunkte erwarten, die die Klassenpfade trennen. – Tom

+1

Windows: Semi-Colons Linux: Doppelpunkte – dm76

Antwort

2

Eigentlich war der Trick in der Reihenfolge der Argumente in der Befehlszeile:

die -cp (oder -classpath) wird zuletzt eingestellt, dann ist es nicht

java Tool -cp .:extern/Hello.jar 

Es funktioniert muss zuerst sein wie:

java -cp .:extern/Hello.jar Tool 

!!!

+3

Ja. Andernfalls wird "-cp whatever" an main() als args-Array übergeben. Sie müssen den Unterschied zwischen Argumenten zur Java-Laufzeit und den Argumenten zu Ihrem Programm beachten. – dsm

+0

Ah ja natürlich, das macht jetzt Sinn - danke für die Erklärung! – dm76

4

Sie die Notwendigkeit Hello.jar auf dem Klassenpfad beim Ausführen sowie beim Kompilieren.

0

Sie müssen die Hello.jar-Datei in den Klassenpfad einschließen, wenn Sie sie ebenfalls starten.

1

Wenn Sie Java ausführen, müssen Sie auch die JAR-Datei hinzufügen (das Hinzufügen des Verzeichnispfads funktioniert nur nicht).

Siehe classpath Informationen.

Es sollte wie folgt sein:

java -classpath /java/MyClasses/myclasses.jar utility.myapp.Cool 
+0

Eigentlich das Semikolon Dinge völlig durcheinander und es sollte wirklich ein Doppelpunkt sein. Der Trick bei dem Problem bestand darin, zuerst die Option -classpath zu verwenden, d. H. Vor Tool. – dm76

+0

Ja, tut mir leid, ich habe den Linux-Teil der Frage irgendwie ignoriert, aber die Antwort aktualisiert, um das zu reflektieren, als ich merkte. – Pool

0

java -cp XXX.jar hallo xxx ist das Glas in Ihrem Classpath haben möchten, wenn Sie sie mehrere Gläser wollen, dann trennen verwenden;

karl

1

Java verwendet dynamische späte Bindung, so in dem Classpath während der Kompilierung die JAR-Putting nur notwendig ist, um sicherzustellen, dass der Code die Klassen aus es richtig verwendet, aber es nicht wirklich betten sie in den Code wie der Linker in C/C++. Daher müssen Sie den Klassenpfad auch beim Ausführen des Codes festlegen.

Dies ist jedoch:

$ javac Tool.java -classpath .:./extern/: 

sollte nicht funktionieren, da JARs Classpath setzen in direkt werden müssen, nicht nur das Verzeichnis der sie leben:

$ javac Tool.java -classpath .:./extern/Hello.jar 

Schließlich sind Sie Platzieren Sie Ihren Code im standardmäßigen namenlosen Paket.Dies ist in Ordnung, um herumzualbern, wird aber auf lange Sicht Probleme verursachen (zum einen können Sie nirgendwo Klassen aus dem Standardpaket importieren).