Hello!
How do you add a folder (e.g. a resource folder containing arts) to the classpath of a netbeans project? I managed to do that manually via editing the NB generated jar file of the project (that is its MANIFEST.MF file + copying the resources manually), but there should be a way to tell netbeans as well to mind the resources, no?
The folder structure looks like this:
/project/art/
/project/dist/lib/
/project/dist/art/
/project/dist/project.jar
/project/lib/
/project/src/
I don't want to package the art into the jar because I'd like the art to be easily exchangeable. If I add the art folder to the src folder then NB compiles fine, but the art resources end up in the jar.
Adding the art folder to the netbeans project libraries (Properties -> Libraries -> Add JAR/Folder) seemed not to work, because then I ended up with an error '...\project\art is a directory or can't be read. Not copying the libraries.' which in turn prevents even the real libraries folder from being copied.
Any ideas?
Best regards Chris
2 Observations made, based on the comments from gpeche: a) Rather specifying the additional resources folder in the "Run" tab than in the "Compile" tab of the project properties -> Libraries doesn't seem to make a lot of difference in Netbeans (I'm currently using 6.9.1). The output (and thus error) stays the same, that is nothing gets copied at all:
Created dir: C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\dist
C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\art is a directory or can't be read. Not copying the libraries.
Not copying the libraries.
Building jar: C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\dist\VocabularyTrainer.jar
Another interesting aspect is that in the help menu of the Libraries panel nothing is explicitly mentioned regarding folders as libraries. Could it be possible, that the button in Netbeans is falsely named, that is only real jar's are allowed?
b) Adding the resources folder to the Libraries list does have the impact though, to add another entry to the MANIFEST.MF. While - and that's the smaller issue - the classpath entry seems to be always expecting the resource folder to be a subfolder of the library folder (e.g. "lib/arts") the major problem is that there seems to be a slash missing. As mentioned the NB generated entry in the MANIFEST.MF will look like this "lib/arts" (which does not work for me), while (manually set) "lib/arts/" does?!
The way I use resources from the folder is something like this:
URL resource = getClass().getResource("/gui/refresh.png");
ImageIcon tmp = new ImageIcon(resource);
Edit:
Based on Tushars comment and this posting I found the following solution to be an acceptable tradeoff between functionality and comfort.
I override the ANT target from the auto generated 'build-impl.xml' file which creates the Class-Path in the MANIFEST.MF file in the basic 'build.xml' file of the Netbeans project. The code which goes to the 'build.xml' file looks like this:
<property name="art.classpath" value="art/" />
<target name="-post-jar">
<mkdir dir="${dist.dir}/art"/>
<copy todir="${dist.dir}/art">
<fileset dir="${basedir}/art">
<!-- <exclude name="**/!source/**"/> if you want to exclude something... -->
</fileset>
</copy>
</target>
<target name="-init-macrodef-copylibs">
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
<element name="customize" optional="true"/>
<sequential>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Class-Path" value="${jar.classpath} ${art.classpath}"/>
<customize/>
</manifest>
</copylibs>
</sequential>
</macrodef>
</target>
The tradeoff is that for development in Netbeans I still have to add the resource folder (e.g. 'art') to the libraries list to make the project run in Netbeans. This will cause an additional entry in the MANIFEST.MF file ('lib/art') along with the effect that the libraries will not get automatically copied to the 'dist' folder, with the message
...\art is a directory or can't be read. Not copying the libraries.
Not copying the libraries.
This behavor is - afaik - intended (to force everything to be bundled up in a jar), even though there are discussions about it going on. To make a real distribution bundle I'd have to take away the resource folder(s) from the library list in NB and rebuild.
Ideas about a more streamlined setup without any tradeoffs are of course still welcome. :)