I have a NetBeans project that relies on one specific Java class in another project. Right now, when NetBeans compiles the project, it only adds a reference to the other Java class, which leads to a NoClassDefFoundError since the external class isn't in the JAR.
How can I force NetBeans to compile that external file into the JAR when it builds, short of copying and pasting it over?
I take it that you are trying to create what it commonly known as a "fat JAR file"; i.e. a JAR file that contains all required classes for your application.
Try the recipe in this forum posting.
Another alternative might be to add something like the following to your Ant buld.xml file.
<target name="-post-jar">
<jar update="true" destfile="${dist.jar}">
<zipfileset src="${javac.classpath}"/>
</jar>
</target>
If it's Maven based, simply use the ant task to copy the class to your target/classes in the appropriate phase (I guess compile-sources or such - something before test).
If it's Ant based, you'd have to hack NetBeans' ant build scripts, which are extensible per-project.
BTW, the standard way is to make the "another project" a dependency of your project. That class might need another classes from that project... and so on.
I might also recommend JDGUI to decompile that project and to cherry-pick the classes you need. http://java.decompiler.free.fr/?q=jdgui
Related
Sorry if the question is basic. I’m trying to build a java project that include text files :
File file = new File("data/include/foo.txt");
Problem is that with Netbeans, Built and Clean actions are done without taking into account external text files.
Can you please help me solving this problem.
In Netbeans there are basically two types of java projects. One is using ANT as its build machine and one is using maven.
Using ANT to build:
You have to modify or build a build.xml. Netbeans offers some targets in its standard build.xml to trigger events on each part of the build process.
So to include some additional resource files (in your case some text files) you should add your build.xml with a target like
<target name="-post-jar">
<jar destfile="dist/myjar.jar" update="true">
<fileset dir="${basedir}">
<include name="data/include/*"/>
</fileset>
</jar>
</target>
It means that after your JAR is build the files from ${basedir}/files/* are included as well.
Using MAVEN to build:
Netbeans uses here completely Mavens infrastructure. So Maven does have a standard mechanism to recognize resource files to include. It all comes down to place these files in a specific place of the project. Assuming you did not change this standard directory layout of maven JAR projects is is something like:
Project
src
main
java
resources
...
So all files placed in src/main/resources (including subfolders) are included in your JAR automatically.
Read more here
Edit 1:
To access this resource files you cannot use File objects. This is done using the class own getResource methods:
App.class.getResourceAsStream("data.xml")
App.class.getResource("data.xml")
Here my class is App and my datafile is data.xml which is in the same directory as my class. This is relative adressed. But if you use a path with a heading / then your path is JAR file absolute. Read more about this here.
If I have a java project that consists of several different types of files (pictures, sound, etc) and multiple jar dependencies, what is a good way to package it all into one single jar that can just be double-clicked?
I know jars by themselves are pretty dumb in that they don't look within themselves for files that they depend on (something I only realized after the slightest bit of frustration (understatement)). -- If jar A depends on classes contained inside jar B, putting jar B inside jar A will not work. Jar A must be in the same directory as jar B.
...Now, I know I could just extract all the files from all the other jars and put everything in the same directory. That would sort of work, but I don't want to do it because: 1. It would be messy and 2. it still wouldn't solve the problem of needing to have the sound files in the same directory as the final jar. (For whatever reason, sound files act the exact same way as internal jars)
Basically, I just want to make it so that the files my application depends on aren't obnoxiously visible and ostentatious. So, if there were some solution where I could put everything inside a jar and have it be the only necessary file to run the entire program, that would be optimal. But, I am willing to accept creative/inventive ways to bypass the problem, such as having a batch script in a parent directory execute the jar or something. (I say "or something" because that exact scenario would only work on windows operating systems. ...you know what I mean!)
Apache Maven plus shade plugin will do exactly what you need.
Check out the "Shade Plugin where a Main-Class is added to the MANIFEST.MF" section here http://maven.apache.org/plugins/maven-shade-plugin/examples.html
You can extract all the JARs and merge them into one common JAR. There are ANT tasks and Maven plugins readily available for doing just this. Additionally, if you're application is properly written, there is nothing preventing you from putting media files and other resources in the JAR as well. You just need to ensure that these resources are "loaded from the classpath", rather than being loaded from the current working directory.
If you use the assembly plugin for maven, you can have it download dependencies, build modules and produce an executable jar.
If you use Maven, then I suggest the shade or assembly plugins.
If not, then read this: Easiest way to merge a release into one JAR file
If you are building an executable jar and have other jars that you need to be available in the classpath, there is a Class-Path: line in the jar's MANIFEST.MF file that lists entries (including jars and directories) to include in the classpath when the main class is run.
I usually use my IDE or ant to build such executable jars and set the Class-Path: header.
By the way, to make your jar executable, set the Main-Class: line in your MANIFEST.MF file.
Here is an example from an executable jar I build:
Main-Class: com.example.app.MyAppCLI
Class-Path: log4j.jar driver.jar libraries.jar
And here is a corresponding ant target to build this:
<target name="exejar">
<jar destfile="myapp.jar"
basedir="bin"
include="**/app/*.class">
<manifest>
<attribute name="Main-Class" value="com.example.app.MyAppCLI"/>
<attribute name="Class-Path" value="log4j.jar driver.jar libraries.jar"/>
</manifest>
</jar>
</target>
If you will use a tool like ant to build your executable jars, it will make the process more easy to repeat, and will also handle strange edge cases for you, like what happens when a header line in MANIFEST.MF gets too long.
If you use Maven, you may a appreciate the onejar-maven-plugin. One major benefit is that all your dependency jars stay in jars, and your code is in its own jar. All of those jars are put in a bigger jar, which is made executable, thus avoiding some potential classpath issues. Read the usage guide and this blog post for more information.
have a java project that consists of several different types of files (pictures, sound, etc) and multiple jar dependencies, what is a good way to package it all into one single jar that can just be double-clicked
A better way to deploy a rich client app. is using Java Web Start. The end user would never see a Jar, and could be provided a desktop short-cut or menu item to launch the app.
In my project I'm using many jar fiels to support the project..as the number of jar files increases I want to move all jar files into a single jar and make use of that.can you provide me useful links that can help me to do this.
Plenty of options -
In Eclipse you can
Create a normal java project with a sample main class
Add jar files to the project
Export it as a runnable jar, which should repackage the all the jars into one.
Do it through an ant task -
<jar destfile="combined.jar">
<zipgroupfileset dir="lib" includes="*.jar" />
</jar>
More tools like jarjar, onejar (and many more) etc are available to do the repackaging.
If you are willing to use ant (which can be called from Eclipse) there are some solutions in this other question here: Clean way to combine multiple jars? Preferably using Ant
I also like proguard, which combines jars and also strips out unused code.
I would recommend you use a maven pom file to maintain your dependancy's. It has a pretty steep learning curve at first, but once you get the hang of it it makes your life so much easier. You would just add all your dependencies in the pom and maven would download and maintain them itself.
I'm using NetBeans to import a series of libraries from my Arduino IDE. I'm following directions from the following link:
http://silveiraneto.net/2009/03/01/arduino-and-java/
This works provided I use the Arduino-0013 version of the IDE install, more current versions do not compile using this method.
I have found that using the Arudino-0013 set as the working directory is NOT necessary if I manually move the "preferences.txt" and "keywords.txt" and "librxtxSerial.so" files into the lib folder in my Java dist (build) folder, and also move the entire Arduino-0013 "Hardware" folder also into my Java dist (build) folder.
When I do this I can run the Java program from the dist directory on the command line. Using the command:
java -jar myProgram.jar
rather than having to go into the Arudino-0013 as my working directory and use -cp to get my program to work (which I haven't worked out how to do incidentally):
Is there a way to include these .txt files and the Arudino hardware folder with all the files it contains when I build the project with NetBeans? The reason I ask is because it's getting annoying having to do this manually every time I do a new build.
My answer is not specific to netbeans but you can try:
Make an Apache ANT build file to build your project. In that file make a copy task which will copy txt files in your build. By doing this you will not have to so it manually. See here: http://wiki.netbeans.org/NetbeansedAnt to know how to work with ANT in NetBeans.
In Netbeans, if you switch from the Projects tab to the Files tab, you'll see that you have a build.xml file. This is an Ant build.xml file. You can configure Ant to automatically copy the files for you whenever your build your project. You would essentially have something like this:
<project ...>
<target name="-pre-compile">
<copy file="some/path/preferences.txt" todir="../some/dir"/>
<copy file="some/path/keywords.txt" todir="../some/dir"/>
<copy file="some/path/librxtxSerial.so" todir="../some/dir"/>
</target>
<target name="-post-compile">
<copy todir="build/dir">
<fileset dir="some/path/Arduino-0013"/>
</copy>
</target>
</project>
There is more information in the build.xml file about what you can and can't hook into. The Ant documentation is good, and the Tasks section of the Ant Manual will be particularly useful.
There should be a dependencies section in NetBeans for your project. You can then add external libraries to your project, such as local JAR files you've got. The best way would probably be to jar up the text files and Arduino directory together, then add that JAR file as a compile-time (and/or run-time) dependency to your project. Now, when you compile your project in NetBeans it should include the specified JAR file on the classpath and voila.
Sorry to not give you more NetBeans-specific direction, I've only used the IDE a couple of times, but all IDEs will allow you to add local JAR files and third-party libraries as dependencies to your project, you just need to find where in the IDE you can do that.
Another idea that might work is to set NetBeans to use your local copy of Java for compilation instead of the one that came bundled with the IDE, that way you don't need to fuss with project dependencies. Again, I don't know where in NetBeans to set this, but start in the General Settings (or perhaps the Project-specific Settings) and find the Java/compilation section; hopefully there's an option to specify which JDK to use, then point it at your local copy.
From Eclipse, I found I can easily export an Ant build file for my project. It provides references to 3rd party libraries and some base targets. I'm using it from my global build file. The only thing that bothers me about this, is that if something is modified in the project structure (like adding a new 3rd party library), we have to think (yes that can be hard sometimes!) about regenerating that build.xml file. I'm wondering if anyone here knows a way to have it updated automatically. By "automatically" I mean that it would not be necessary to explicitly ask Eclipse to regenerate it every time it's needed. I don't know what could be the trigger though...
Any thoughts or knowledge on this?
Thanks!
MJ
Right-click on an Eclipse project then "Export" then "General" then "Ant build files". I don't think it is possible to customise the output format though.
I have been trying to do the same myself. What I found was that the "Export Ant Buildfile" gets kicked off in the org.eclipse.ant.internal.ui.datatransfer.AntBuildfileExportPage.java file. This resides in the org.eclipse.ant.ui plugin.
To view the source, use the Plug-in Development perspective and open the Plug-ins view. Then right-click on the org.eclipse.ant.ui plugin and select import as > source project.
My plan is to create a Java program to programmatically kick off the ant buildfile generation and call this in an Ant file every time I build by adding the ant file to the builders of my projects (Right-click preferences on a projet, under the builders tab).
I've had the same problem, our work environment is based on Eclipse Java projects, and we needed to build automatically an ANT file so that we could use a continuous integration server (Jenkins, in our case).
We rolled out our own Eclipse Java to Ant tool, which is now available on GitHub:
ant-build-for-java
To use it, call:
java -jar ant-build-for-java.jar <folder with repositories> [<.userlibraries file>]
The first argument is the folder with the repositories. It will search the folder recursively for any .project file. The tool will create a build.xml in the given folder.
Optionally, the second argument can be an exported .userlibraries file, from Eclipse, needed when any of the projects use Eclipse user libraries. The tool was tested only with user libraries using relative paths, it's how we use them in our repo. This implies that JARs and other archives needed by projects are inside an Eclipse project, and referenced from there.
The tool only supports dependencies from other Eclipse projects and from Eclipse user libraries.
Take a look at the .classpath file in your project, which probably contains most of the information that you want. The easiest option may be to roll your own "build.xml export", i.e. process .classpath into a new build.xml during the build itself, and then call it with an ant subtask.
Parsing a little XML sounds much easier to me than to hook into Eclipse JDT.
If all you need is the classpath entries, I do something like the following to use the eclipse build path.
<xmlproperty file=".classpath" collapseAttributes="true" delimiter=";" />
Then set that value in the path
<path id="eclipse.classpath">
<pathelement path="${classpath.classpathentry.path}"/>
</path>
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" updatedProperty="compiled">
<classpath refid="eclipse.classpath"/>
</javac>
</target>
I'm the one who donated the Ant export filter to Eclipse. I added the auto export feature, but only to my personal plug-in eclipse2ant, which I still maintain to coordinate bug fixes.
Unfortunately I have no time to merge it to the official Eclipse builds.
Select File > Export from main menu (or right click on the project name and select Export > Export…).
In the Export dialog, select General > Ant Buildfiles as follows:
Click Next. In the Generate Ant Buildfilesscreen:
Check the project in list.
Uncheck the option "Create target to compile project using Eclipse compiler" - because we want to create a build file which is independent of Eclipse.
Leave the Name for Ant buildfile as default: build.xml
Click Finish, Eclipse will generate the build.xml file under project’s directory as follows:
Double click on the build.xml file to open its content in Ant editor:
source