我正在尝试使用Amazon Mechanical Turk API构建一个jar文件。 SDK附带了一个helloworld文件,我正试图将其作为一个完整性检查 - 它位于:
http://aws.amazon.com/code/SDKs/695
设置完所有内容后,我可以使用提供的build.xml文件使用ant来正确构建和执行。
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可由其他人执行,而无需安装库。似乎“正确”的方法是从ant中构建一个jar。
我的理解是我需要包括:
我不知道是否需要包含其他任何内容。我知道在运行时有一个很复杂的类路径,我可以在命令行中指定类路径,但我怀疑类路径的硬编码会阻止我分发.jar文件,这就是整个点。
以下是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>
这构建。当我运行jar时,它会崩溃,但是:
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中的文件:
jar tf helloworld.jar | grep hello
build/private/classes/samples/helloworld/
samples/helloworld/
build/private/classes/samples/helloworld/MTurkHelloWorld.class
samples/helloworld/MTurkHelloWorld.java
这表明,如果将类路径设置为build / private / classes / samples /,它可以正常工作:
<attribute name="Class-Path" value="build/private/classes/samples/helloworld" />
这会导致相同的错误。我认为我在这里缺少一些非常基本的东西,我会感激任何帮助!
答案 0 :(得分:3)
你的package-folder必须直接启动,你不能将它们放在jar文件的任何子目录中:
它必须如下所示:
helloworld/
helloworld/MTurkHelloWorld.class
您的jar-task必须如下所示:
<jar destfile="helloworld.jar" basedir="${sample.classes.dir}">>
<manifest>
<attribute name="Main-Class" value="MTurkHelloWorld" />
</manifest>
</jar>
basedir是已编译包的来源。
使用<fileset />
,您只需添加普通文件。
此外,您不能将外部库放入jar文件中。它们必须与jar,java classpath
或清单的classpath-attribute
指定的文件夹位于同一文件夹中。
或者您可以使用one jar task将类包含在jar中。