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

5

14

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.

Gallaher answered 5/2, 2012 at 23:33 Comment(5)
If you are able to get jar files into the project jar file, what program are you going to use to read those internal jar files? I don't think the java command knows how to read from jar files contained in a jar file.Alden
@Alden Hi, I don't need to get jars inside of the project jar: I just want to have jars which are dependencies of the project's dependencies to be copied into the project's lib folder.Gallaher
You do not miss anything. You can not do this using wizard or property dialogue in NetBeans projects. I recommend to learn Maven, NetBeans Maven Projects fill all your requirements.Acariasis
@UnaiVivi I am stuck upon the same problem. Did you manage to solve it?Figge
@Figge Unfortunately I haven't. Still keeping track of libs by hand... Please do keep an eye here: if I happen to find a solution I'll post it. CheersGallaher
U
10

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.

Unarm answered 6/8, 2013 at 19:50 Comment(0)
F
5

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.

Furgeson answered 10/10, 2013 at 12:6 Comment(0)
S
3

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.

Sorbian answered 3/2, 2015 at 7:37 Comment(2)
Very elegant and effective solutionGallaher
thank you! FWIW, I only added failonerror="false" in the finalcopy task of build-import-libraries.xml. Otherwise, the script would fail for dependencies without dependencies :)Reinert
P
1

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>
Pragmaticism answered 26/1, 2013 at 1:36 Comment(2)
Nope, not using Maven: using Ant.Gallaher
This is not be useful for users using ant, however it works like a charm for maven.Restorative
T
0

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.

Transfiguration answered 20/8, 2012 at 11:13 Comment(2)
That copies dependant libraries and that's the option that is already copying the library jars to the dist folder; what I need to do is to copy dependant libraries' dependant libraries, and that option doesn't do that (unfortunately)...Gallaher
Also. When you invoke the build from command line Ant (like in a Jenkins build), this option seems to be ignored.Assignment

© 2022 - 2024 — McMap. All rights reserved.