How can I have Netbeans automatically copy 3rd party jars from an included class-library to my project's dist/lib directory?

StackOverflow https://stackoverflow.com/questions/9154122

Domanda

I have a Java Application in NetBeans 7.1 (let's call it myApp) that depends on a Java Class-Library Project [more than one, actually] where I keep some utility-classes I share among projects.

This Class-Library Project (let's call it myLib) depends on [many] third party libraries (e.g. apache-commons-younameit.jar).

I included myLib as a library, and NetBeans' Ant script pulls myLib.jar in the dist/lib directory of my myApp project; however, the jars upon which myLib depends are not pulled in together with myLib, so my project gets runtime exceptions due to the missing apache-commons-youtnameit.jar.

I would like to have both myLib.jar and apache-commons-younameit.jar automatically pulled into myApp's dist/lib folder, so that I don't have to manually check all of my libraries' dependencies and add them to my main project.

  • Is there an obvious way to accomplish this through NetBeans dialogs that I'm missing?
  • or is it necessary to manually tweak my build.xml? If so, could you kindly post an example? (I'm not that well up on Ant)

What I'd like to avoid is the following:

  1. I need to add a new utility library, picking from my Java Class-Library Projects.
  2. I lookup into that library's libraries what jars are used and write them down.
  3. I go back to my main project and add those 3rd party libraries (only the ones that I haven't included already for direct use from within my main project itself).

Thank you in advance for any help, or for pointing me in the right direction.

È stato utile?

Soluzione

I found a way to copy "dependant libraries' dependant libraries" as you said in one of the comments. Hopefully this helps.

Add the following code to your NetBean project's build.xml file, after the <import file="nbproject/build-impl.xml"/> line. You will need to fill out a proper relative path in the <fileset> tags below.

<!--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>

Not the cleanest code, but it solved the problem for me. You'll need to manually update this as you add extra dependant projects to your main project.

Altri suggerimenti

This is what worked for me in Netbeans 7.3:

Right-click on your project and select Properties, then select Libraries on the right side.

Then under "Libraries Folder" click the "Browse..." button: Properties dialog

Then choose your lib folder, unless it is already chosen automatically by Netbeans: Add Libraries Folder dialog

Then click Next, Finish as needed and when you come back to the Properties dialog, you should have: Properties dialog final Setup

After that, Netbeans should both copy the lib folder into dest and, most importantly, will reference all your libraries in the MANIFEST.MF file in your main JAR.

As a test, look if there is a new CopyLibs folder in the lib folder. Inside CopyLibs there should be a org-netbeans-modules-java-j2seproject-copylibstask.jar file. Netbeans added these and this is, I presume, what drives the copying of the lib folder into dist.

I had the same problem and I wrote an ant task to automatically copy the dependent libraries from all included class-library projects into my main-project(s). You don't need to include any third party libraries for this to run.

The Copy Dependent Libraries checkbox in the class-library project options must be set for this to work. Then Netbeans copies all dependent libraries into the class-library project's dist/lib folder, similar to Gregory's solution. The advantage of this method is, when you include more class-libraries to your main-project, you don't need to adapt your build.xml each time.

How it works

My ant task first searches the main-project's properties for the paths of all included projects, then opens their project.properties file, reads the class-library project's dist-folder and copies all libraries in the dist-folder's lib directory to the main-project's lib folder.

There is also a test if Copy Dependent Libraries is enabled.

The code

The file build-import-libraries.xml in the project's parent folder :

<?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>

Include this line in your build.xml, after <import file="nbproject/build-impl.xml"/> (you may need to adapt the path to build-import-libraries.xml in the import task) :

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

This works for Java SE Applications and Java Web Applications. I have only tested this in Netbeans version 8.0.2. I hope this will keep working in future versions.

Lee's answer works with a Java Application project in NetBeans 7.2. If you want to use Maven in NetBeans, you'll have to create a Maven Java Application project. Modify the pom.xml file to include the 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>

Assuming that you have added them all to your project classpath(under Libraries in the project properties). You can go into Build > Packaging and tick Copy Dependant Libraries.

I am using Netbeans 7.2.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top