Понимание JAR-файлов и пакетов в Java - PullRequest
0 голосов
/ 16 марта 2011

Я пытаюсь понять, как банки и пакеты работают в Java.Поэтому для этого я создал простой тестовый JAR и пытаюсь использовать класс, содержащийся в этом jar.Достаточно просто, но это дает мне ошибки типа "класс не найден".Вот настройки:

1) У меня есть файл с именем MyHelloWorld.java, который будет упакован в JAR:

package com.mytest;

public class MyHelloWorld {
    public String getHello() {
        return "Hello";
    }
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

2) У меня есть другой файл с именем 'HelloHello.java'который использует функцию getHello() в com.mytest.MyHelloWorld

import com.mytest.*;

public class HelloHello {
    public static void main (String[] args) {
        MyHelloWorld hello = new MyHelloWorld();
        System.out.println(hello.getHello());
    }
}

3) Чтобы упаковать класс MyHelloWorld внутри JAR, я создал папки com/mytest в текущем каталоге и переместил MyHelloWorld.javaв эту папку

4) Я скомпилировал MyHelloWorld.java в этой папке, используя javac MyHelloWorld.java

5) Я запустил jar -cf myhello.jar ./com/mytest/*.class из корневой папки, чтобы создать файл JAR (как описано в http://www.javacoffeebreak.com/faq/faq0028.html)

6) Я скопировал HelloHello.java и myhello.jar в новую папку, в которой больше ничего нет, чтобы проверить эту настройку

7) javac -cp ./*.jar HelloHello.java [успешно]

8) java -cp ./*.jar HelloHello [FAILS] (я также попробовал просто `java HelloWorld ', что тоже не удалось, с другим сообщением об ошибке)

Этот последний оператор завершается ошибкой с сообщением:

$java -cp ./*.jar HelloHello
Exception in thread "main" java.lang.NoClassDefFoundError: HelloHello
Caused by: java.lang.ClassNotFoundException: HelloHello
    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:315)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398)

Есть идеи, почему это не удается?Любые идеи, которые вы можете сообщить о том, почему он работает таким образом, и как имена пакетов определяются внутри JAR и т. Д., Также приветствуются!

Ответы [ 4 ]

5 голосов
/ 16 марта 2011

Я полагаю, что он ищет в банке ваш класс HelloHello. Возможно, вам также нужна текущая папка на пути к классам.

java -cp .:myhello.jar HelloHello
1 голос
/ 16 марта 2011

Вы должны использовать:

java -cp .:./* HelloHello

java и javac обрабатывают аргумент -cp немного по-другому. С java * в cp автоматически загрузит все банки, которые он найдет в данном месте.

Кроме того, двоеточие : является разделителем между различными элементами classpath.

0 голосов
/ 16 марта 2011

хорошо, java HelloHello тоже работает

0 голосов
/ 16 марта 2011

Убедитесь, что HelloHello.class находится в соответствующей структуре каталогов (com / mytest), чем измените ваш 8-й шаг:

8) java com.mytest.HelloHello //or java -cp .;*.jar com.mytest.HelloHello
...