Я пытаюсь создать файл jar с помощью Amazon Mechanical Turk API. SDK поставляется с файлом helloworld, который я пытаюсь собрать в качестве проверки работоспособности - он находится здесь:
http://aws.amazon.com/code/SDKs/695
После настройки я могу использовать ant для правильной сборки и выполнения, используя прилагаемый файл build.xml.
bash-3.2$ ant helloworld
ant helloworld
Buildfile: /Users/astorer/Work/dtingley/java-aws-mturk-1.2.2/build.xml
compile-sample:
[echo] Compiling the sample java source files...
[javac] /Users/astorer/Work/dtingley/java-aws-mturk-1.2.2/build.xml:252: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
helloworld:
[echo] Running the Hello World sample application...
[java] Got account balance: 10000.00
[java] Created HIT: 2RB2D5NQYN5F41KJ2IKYPNCW2H3A60
[java] You may see your HIT with HITTypeId '22R58B727M0IHQ4HZEXYISVF4XCWBC' here:
[java] http://workersandbox.mturk.com/mturk/preview?groupId=22R58B727M0IHQ4HZEXYISVF4XCWBC
[java] Success.
BUILD SUCCESSFUL
Total time: 11 seconds
Я хочу, чтобы helloworld мог выполняться кем-то другим без установки библиотек. Кажется, что «правильный» способ сделать это - создать банку из муравья.
Насколько я понимаю, мне нужно включить:
- необходимые библиотеки, собранные из самого SDK (и предоставленные в виде .jar)
- встроенный файл класса helloworld
- атрибут манифеста, определяющий основной класс для запуска
Я не знаю, нужно ли мне что-то еще включать. Я знаю, что во время выполнения есть большой и сложный путь к классам, и что я могу указать путь к классам в командной строке, но я подозреваю, что жесткое кодирование пути к классам не позволит мне распространять файл .jar, который и составляет весь смысл.
Вот фрагмент build.xml для фляги:
<target name="hellojar" depends="helloworld" description="Creates Jar of helloworld" >
<jar destfile="helloworld.jar">
<fileset file="${sdk.jar}" />
<fileset dir="${sample.classes.dir}/helloworld/" />
<fileset dir="."/>
<manifest>
<attribute name="Main-Class" value="MTurkHelloWorld" />
</manifest>
</jar>
</target>
Это строит. Когда я запускаю флягу, она вылетает, однако:
bash-3.2$ java -jar helloworld.jar
java -jar helloworld.jar
Exception in thread "main" java.lang.NoClassDefFoundError: MTurkHelloWorld (wrong name: helloworld/MTurkHelloWorld)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Это имеет смысл, потому что мой MTurkHelloWorld фактически находится в пакете helloworld. Таким образом, я должен изменить на:
<manifest>
<attribute name="Main-Class" value="helloworld.MTurkHelloWorld" />
</manifest>
Это успешно строится. Когда я запускаю его:
bash-3.2$ java -jar helloworld.jar
java -jar helloworld.jar
Exception in thread "main" java.lang.NoClassDefFoundError: helloworld/MTurkHelloWorld
Caused by: java.lang.ClassNotFoundException: helloworld.MTurkHelloWorld
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Мы можем исследовать файлы в банке:
jar tf helloworld.jar | grep hello
build/private/classes/samples/helloworld/
samples/helloworld/
build/private/classes/samples/helloworld/MTurkHelloWorld.class
samples/helloworld/MTurkHelloWorld.java
Что говорит о том, что, возможно, если бы classpath был установлен для сборки / private / classes / samples /, он бы работал правильно:
<attribute name="Class-Path" value="build/private/classes/samples/helloworld" />
Это приводит к идентичной ошибке. Я думаю, что здесь есть что-то довольно фундаментальное, что мне не хватает, и я был бы признателен за любую помощь!