所以我现在意识到我的错误源于命令行启动,而不是点击它们启动jar。基本上,如果我从任何文件夹运行jar,但他们实际驻留的文件夹,那么我的资源被错误地引用。如果我从同一文件夹执行命令行,则此问题就会消失。 所以问题是如何相对地引用jar和资源,无论从哪里调用执行?
我有几个问题试图建立一个用于分发的项目。项目结构是这样的,我有6个包。每个包都分为两个子包Gui和Engine。每个子包都有一个可运行的主类。 “Common”包是其他包的包装器,无论选择哪个包都会启动。我的目标是将每个包装成独立的引擎方面。这用于引擎的命令行测试。 “Common”jar与所有资源放在一起并运行整个应用程序。
我的问题源于需要清理项目。因此,正在进行重新分解和重新打包,但是当前用于构建和jar项目的方法是批处理脚本,它将类文件(遵循包/文件夹结构)复制到结束文件夹位置。从那里开始创建jar的命令行,并在清单文件中概述类路径和主类。这很好用,jars用正确的结构和类路径编译,一切都正常运行。但是,保持xcopy命令正确是一件很痛苦的事情,因为它需要更改为包结构改变的位置,以及位置,具体取决于谁在构建项目。
所以我的解决方案是使用build.xml并为netbeans概述ant build。这将尊重任何项目结构更改并使构建内部保持netbeans。我遇到的确切问题是无论使用何种构建方法。(批处理/构建脚本)我使用任一方法在jar中获得确切的文件夹结构,并且类路径完全相同。我的common.jar适用于该项目,但我的引擎测试罐会遇到类路径或引用问题。我将包括大部分的ant脚本,批处理文件和使用的清单文件。
批处理文件
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Common C:\Emerson\Common\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Common\gui C:\Emerson\Common\gui\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Common\Meg C:\Emerson\Common\Meg\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Pressu re C:\Emerson\Pressure\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Pressure\Gui C:\Emerson\Pressure\Gui\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Pressure\Meg C:\Emerson\Pressure\Meg\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\PressureV2 C:\Emerson\PressureV2\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\PressureV2\Gui C:\Emerson\PressureV2\Gui\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\PressureV2\Gui\controller C:\Emerson\PressureV2\Gui\controller
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\PressureV2\Gui\models C:\Emerson\PressureV2\Gui\models
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\PressureV2\Gui\rules C:\Emerson\PressureV2\Gui\rules
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Temp\Gui C:\Emerson\Temp\Gui\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\Temp\Meg C:\Emerson\Temp\Meg\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\rfdFlow\Gui C:\Emerson\rfdFlow\Gui\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\rfdFlow\Meg C:\Emerson\rfdFlow\Meg\
xcopy /Y C:\Users\tfollansbee\Documents\NetBeansProjects\Emerson\branches\Merge\build\classes\utils C:\Emerson\utils\
"C:\Program Files\Java\jdk1.6.0_25\bin\jar" cvmf mainClass tempAsynch.jar Temp/*
"C:\Program Files\Java\jdk1.6.0_25\bin\jar" cvmf mainClass Common.jar Common/*
"C:\Program Files\Java\jdk1.6.0_25\bin\jar" cvmf pressureClass Pressure.jar Pressure/*
"C:\Program Files\Java\jdk1.6.0_25\bin\jar" cvmf pressureV2Class PressureV2.jar PressureV2/*
"C:\Program Files\Java\jdk1.6.0_25\bin\jar" cvmf rfdClass rfdFlow.jar rfdFlow/*
"C:\Program Files\Java\jdk1.6.0_25\bin\jar" cvmf pressureV2Class utils.jar utils/*
rmdir /s /q C:\Emerson\Common
rmdir /s /q C:\Emerson\Pressure
rmdir /s /q C:\Emerson\PressureV2
rmdir /s /q C:\Emerson\Temp
rmdir /s /q C:\Emerson\rfdFlow
rmdir /s /q C:\Emerson\utils
xcopy /Y C:\Emerson\Common.jar C:\GCCDEV
xcopy /Y C:\Emerson\tempAsynch.jar C:\GCCDEV
xcopy /Y C:\Emerson\Pressure.jar C:\GCCDEV
xcopy /Y C:\Emerson\PressureV2.jar C:\GCCDEV
xcopy /Y C:\Emerson\rfdFlow.jar C:\GCCDEV
xcopy /Y C:\Emerson\utils.jar C:\GCCDEV
构建脚本
<?xml version="1.0" encoding="UTF-8"?>
<project name="Emerson" default="default" basedir=".">
<description>Builds, tests, and runs the project Emerson.</description>
<property environment="env"/>
<property name="baseDir" value="build/classes/" />
<property name="cp" value=" . utils.jar lib/pfcasync.jar lib/poi-3.7/poi-ooxml-schemas-3.7-20101029.jar lib/poi-3.7/poi-3.7-20101029.jar lib/poi-3.7/poi-ooxml-3.7-20101029.jar lib/poi-3.7/ooxml-lib/xmlbeans-2.3.0.jar lib/poi-3.7/ooxml-lib/dom4j-1.6.1.jar lib/xom/xom-1.2.7.jar lib/jgoodies/jgoodies-common-1.3.0.jar lib/jgoodies/jgoodies-binding-2.6.0.jar lib/resources/** Common.jar
" />
<import file="nbproject/build-impl.xml"/>
<target name="-pre-jar">
<echo message="-pre-jar" />
<delete dir="${env.PTC_STD}/lib/" />
<delete dir="${env.PTC_STD}/resources/" />
<!--delete dir="${env.PTC_STD}/build/" /-->
<echo message="aJar" />
<jar destfile="${env.PTC_STD}/Common.jar" basedir="${baseDir}">
<manifest>
<attribute name="Class-Path" value="${cp}" />
<attribute name="Main-Class" value="Common.gui.emersonWrapper" />
</manifest>
</jar>
<jar destfile="${env.PTC_STD}/tempAsynch.jar" index="false" basedir="${baseDir}" includes="Temp/**">
<manifest>
<attribute name="Class-Path" value="${cp}" />
<attribute name="Main-Class" value="Temp.Meg.tempasynch" />
</manifest>
</jar>
<jar destfile="${env.PTC_STD}/Pressure.jar" index="false" basedir="${baseDir}" includes="Pressure/**">
<manifest>
<attribute name="Class-Path" value="${cp}" />
<attribute name="Main-Class" value="Pressure.Meg.P3051STest" />
</manifest>
</jar>
<jar destfile="${env.PTC_STD}/PressureV2.jar" index="false">
<fileset dir="${baseDir}">
<include name="PressureV2/**" />
<include name="utils/**" />
</fileset>
<manifest>
<attribute name="Class-Path" value="${cp}" />
<attribute name="Main-Class" value="PressureV2.Gui.PressureV2Main" />
</manifest>
</jar>
<jar destfile="${env.PTC_STD}/rfdFlow.jar" index="false" basedir="${baseDir}" includes="rfdFlow/**">
<manifest>
<attribute name="Main-Class" value="rfdFlow.Meg.main" />
<attribute name="Class-Path" value="${cp}" />
</manifest>
</jar>
<jar destfile="${env.PTC_STD}/utils.jar" index="false" basedir="build/classes/" includes="utils/**">
<manifest>
<attribute name="Class-Path" value="${cp}" />
<attribute name="Main-Class" value="PressureV2.Gui.PressureV2Main" />
</manifest>
</jar>
<copy todir="C:/Emerson/resources/">
<fileset dir="resources/">
<exclude name="**/*.svn"/>
</fileset>
</copy>
<copy todir="C:/Emerson/lib/">
<fileset dir="lib/">
<include name="**/*.jar" />
<include name="**/resources/**" />
</fileset>
</copy>
</target>
</project>
常见的清单文件。包含的类路径在所有其他清单文件中完全相同
Main-Class: Common.gui.emersonWrapper
Class-Path: . utils.jar lib/pfcasync.jar lib/poi-3.7/poi-ooxml-schemas-3.7-20101029.jar lib/poi-3.7/poi-3.7-20101029.jar lib/poi-3.7/poi-ooxml-3.7-20101029.jar lib/poi-3.7/ooxml-lib/xmlbeans-2.3.0.jar lib/poi-3.7/ooxml-lib/dom4j-1.6.1.jar lib/xom/xom-1.2.7.jar lib/jgoodies/jgoodies-common-1.3.0.jar lib/jgoodies/jgoodies-binding-2.6.0.jar lib/resources/** Common.jar
在运行时,jar都与“lib”文件夹一起存在于同一文件夹中,该文件夹包括所有引用的库jar。随着一些图像和一些xml数据。我在创建jar时注意到的一个区别是批处理文件没有创建索引。最初在我的蚂蚁脚本中我有index =“true”,当运行例如pressure.jar时我会得到一个 java.lang.NoClassDefFoundError。 我设置index =“false”并且我的这些错误消失了,但是在lib / resources / xml / a.xml中找不到我的相对pathed xml文件 所有这些中真正的踢球者是构建方法之间的差异。我花了两天时间浏览jar结构,文件夹结构和类路径。在build.xml中,我甚至链接到批处理文件中使用的清单文件,但没有成功。一切都是一样的,为什么这些罐子在运行时的行为方式存在差异。我觉得我错过了一个微小的细节。
答案 0 :(得分:0)
不完全清楚你的问题是什么,所以这是我的观察:
以下答案演示了ANT manifestclasspath任务如何用于在可执行jar清单中动态构建“Class-Path”属性:
Ant - how to get all files' name in a specific folder
如果您的构建版本管理了大量开源jar,那么请考虑使用Apache ivy插件自动为您下载它们。
您可以更好地部署一个专用的存储库管理器,如Nexus来托管所有构建依赖项。