如何让Netbeans自动将第三方jar从包含的类库复制到我的项目的dist / lib目录?

时间:2012-02-05 23:33:13

标签: netbeans jar dependency-management class-library netbeans-7.1

我在NetBeans 7.1中有一个Java应用程序(我们称之为myApp)依赖于Java类库项目[实际上不止一个],我保留了一些我在项目中共享的实用程序类。

这个类库项目(我们称之为myLib)取决于[许多]第三方库(例如apache-commons-younameit.jar)。

我将myLib作为库包含在内,NetBeans的Ant脚本将myLib.jar拉入myApp项目的dist/lib目录中;但是,myLib所依赖的jar不会与myLib一起被拉入,因此我的项目因缺少apache-commons-youtnameit.jar而获得运行时异常。

我想将myLib.jar和apache-commons-younameit.jar自动拉入myApp的dist/lib文件夹,这样我就不必手动检查所有库的依赖关系并添加它们到我的主要项目。

  • 是否有一种明显的方法可以通过我缺少的NetBeans对话框来实现这一目标?
  • 还是需要手动调整build.xml?如果是这样,你能发布一个例子吗?(我在Ant上的表现不是很好)

我想避免的内容如下:

  1. 我需要添加一个新的实用程序库,从我的Java类库项目中挑选。
  2. 我查找了该库的库,使用了哪些罐子并将其写下来。
  3. 我回到我的主项目并添加那些第三方库(只有那些我尚未包含在我的主项目中直接使用的库)。
  4. 提前感谢您的帮助,或指导我朝着正确的方向前进。

5 个答案:

答案 0 :(得分:9)

我发现了一种复制“依赖库”依赖库的方法,就像你在其中一篇评论中所说的那样。希望这会有所帮助。

<import file="nbproject/build-impl.xml"/>行之后,将以下代码添加到NetBean项目的build.xml文件中。您需要在下面的<fileset>标记中填写正确的相对路径。

<!--Copy over any "dependant libraries' dependant libraries" -->
<target name="-post-jar">
    <echo>Copying over extra jars into PROJECTNAME</echo>
    <copy todir="./dist/lib">
        <!-- put in order from least important to most important to prevent file overwrites -->
        <fileset dir="path-to-other-nb-project/dist/lib"></fileset>
        <fileset dir="path-to-second-nb-project/dist/lib"></fileset>
    </copy>
</target>

不是最干净的代码,但它解决了我的问题。在向主项目添加额外的依赖项目时,您需要手动更新它。

答案 1 :(得分:5)

这在Netbeans 7.3中对我有用:

右键单击项目并选择“属性”,然后选择右侧的“库”。

然后在“Libraries Folder”下单击“Browse ...”按钮: Properties dialog

然后选择你的lib文件夹,除非它已被Netbeans自动选择: Add Libraries Folder dialog

然后根据需要单击“下一步”,“完成”,当您返回“属性”对话框时,您应该: Properties dialog final Setup

之后,Netbeans应该将lib文件夹复制到dest中,最重要的是,它将引用主JAR中MANIFEST.MF文件中的所有库。

作为测试,查看lib文件夹中是否有新的CopyLibs文件夹。在CopyLibs里面应该有一个org-netbeans-modules-java-j2seproject-copylibstask.jar文件。 Netbeans添加了这些,我认为这是推动将lib文件夹复制到dist的原因。

答案 2 :(得分:3)

我遇到了同样的问题,我编写了一个ant任务来自动将所有包含的类库项目中的依赖库复制到我的主项目中。您无需包含任何第三方库即可运行。

必须设置类库项目选项中的复制相关库复选框才能使其生效。然后Netbeans将所有依赖库复制到类库项目的 dist / lib 文件夹中,类似于Gregory's solution。这种方法的优点是,当您在主项目中包含更多类库时,您不需要每次都调整 build.xml

如何运作

我的ant任务首先在main-project的属性中搜索所有包含项目的路径,然后打开它们的 project.properties 文件,读取类库项目的dist-folder并复制所有库dist-folder的lib目录到main-project的lib文件夹。

如果启用了复制相关库,还会进行测试。

代码

项目父文件夹中的文件 build-import-libraries.xml

<?xml version="1.0" encoding="UTF-8"?>
 <!--
      Custom import of libraries.
      This is not done in Netbeans, because the dist folder is created at runtime.

      To work correctly, disable the compile on save feature for your project.

      Author: Christophe Weis
 -->
<project name="IncludeLibraries" default="default" basedir=".">
    <description>Includes dependent libraries in projects using class-library projects.</description>
    <dirname property="IncludeLibraries.basedir" file="${ant.file.IncludeLibraries}"/>
    <target name="copy-files">
        <!-- Set variable to the folder where to copy the files to -->
        <condition property="libdestdir" value="${build.web.dir}/WEB-INF/lib" else="${dist.dir}/lib">
            <isset property="build.web.dir"/>
        </condition>
        <echo message="Custom build step in file '${ant.file}': copying dependent libraries from included Netbeans projects to '${libdestdir}'" level="info"/>
        <echo message="Please make sure that 'Copy Dependent Libraries' is enabled in Netbeans project options for each included project" level="info"/>
        <copy-dependent-libs>
            <propertyset id="properties-starting-with-project">
                <propertyref prefix="project."/>
            </propertyset>
        </copy-dependent-libs>
    </target> <!-- End custom import -->

    <scriptdef name="copy-dependent-libs" language="javascript">
        <element name="propertyset" type="propertyset"/>
        <![CDATA[
            // Ant uses the Rhino JavaScript implementation

            propertySets = elements.get("propertyset");
            // loop all nested property sets
            for (i = 0; i < propertySets.size(); ++i) {
                propertySet = propertySets.get(i);
                properties = propertySet.getProperties();
                for (var iterator = properties.entrySet().iterator(); iterator.hasNext();) {
                    var entry = iterator.next();
                    var key = entry.getKey();
                    if ("project.licensePath".equals(key)) {
                        continue;
                    }
                    var value = entry.getValue();

                    // read the referenced project's property file
                    var file = new java.io.File(project.getBaseDir(), value + "/nbproject/project.properties");
                    var inputStream = new java.io.FileInputStream(file);
                    var projectProperties = new java.util.Properties();
                    projectProperties.load(inputStream);
                    inputStream.close();
                    var distFolder = projectProperties.getProperty("dist.dir");

                    // check if 'Copy Dependent Libraries' is enabled
                    var doNotCopyDependentLibraries = projectProperties.getProperty("mkdist.disabled");
                    doNotCopyDependentLibraries = java.lang.Boolean.parseBoolean(doNotCopyDependentLibraries);
                    if (doNotCopyDependentLibraries) {
                        self.fail("Please enable 'Copy Dependent Libraries' in project properties for project " + projectProperties.getProperty("application.title", value));
                    }

                    t = project.createTask("copy-files-from-libfolder");
                    // set the dist folder's lib directory
                    t.setDynamicAttribute("fromdir", value + "/" + distFolder + "/lib");
                    t.perform();
                }
            }
        ]]>
    </scriptdef>

    <macrodef name="copy-files-from-libfolder">
        <attribute name="fromdir" />
        <sequential>
            <echo message="Copying libraries from directory '@{fromdir}' to '${libdestdir}'" level="verbose" />
            <copy todir="${libdestdir}">
                <fileset dir="@{fromdir}">
                    <!-- Enable this if you wish
                    <exclude name="servlet-api.jar"/>
                    -->
                </fileset>
            </copy>
        </sequential>
    </macrodef>

</project>

<import file="nbproject/build-impl.xml"/>之后的build.xml中包含此行(您可能需要在导入任务中调整 build-import-libraries.xml 的路径):

<!-- 
     Custom import of libraries.
-->
<import file="../build-import-libraries.xml" as="include-libraries" />
<target name="-post-compile" depends="include-libraries.copy-files" />

这适用于Java SE应用程序和Java Web应用程序。我只在Netbeans版本8.0.2中测试过这个。我希望这将继续适用于未来的版本。

答案 3 :(得分:1)

Lee的回答适用于NetBeans 7.2中的Java Application项目。如果要在NetBeans中使用Maven,则必须创建Maven Java Application项目。修改pom.xml文件以包含maven assembly plugin

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <mainClass>your.app.MainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

答案 4 :(得分:0)

假设您已将它们全部添加到项目类路径中(在项目属性中的Libraries下)。您可以进入Build > Packaging并勾选Copy Dependant Libraries

我正在使用Netbeans 7.2。