I wrote a small OpenGL library for private use.
It is based on Lwjgl. I am programming with eclipse.
Now I want to export this library to have one JarFile, which
I can add to the build path of a project and the user can
only use the library and not lwjgl. So I want to keep lwjgl and the
native files in the build path but export it with my library as one jar.
How could I achieve this?
You can consider using maven to help manage your project life cycle. While there are many other tools out there, maven has been one of the more widely used so if you encountered any difficulties, it won't be hard to find solutions.
Maven can be used to build and package your artifacts, and manage your dependencies (in this case lwjgl and other dependencies lwjgl needs). Since you are already using Eclipse, you can easily use it to create a maven project. (Refer this post here for guidance). From there, Eclipse will help to manage all your build/class paths.
Project Structure
After you create your maven project in Eclipse, you will see that under the project root folder, there is at least:
a pom.xml file. Maven uses this file to determine anything and everything about your project including dependencies.
a src/main folder. This is where you will keep all your Java source codes.
a src/test folder. This is where you will keep all your test codes.
Managing Your Dependencies
The next step involves modifying your pom.xml to specify lwjgl as a dependency. To do so, add the following dependency configuration to your pom.xml
<dependency>
<groupId>org.lwjgl.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<version>2.9.1</version>
</dependency>
Note that this <dependency> configuration should be added to a parent <dependencies> section.
This will download the main lwjgl.jar (version 2.9.1) and the natives for Windows, Linux and Mac OSX from the Maven Central Repository into your project (so you don't have to manage it manually, say in a separate lib folder).
Export Your Project As A JAR
If all went well, you will be able to build your project by navigating to your project root from command line (you can do this in Eclipse too), and issue the command
mvn clean install
which will build your Java codes, execute your unit tests suite (if any), download any dependencies specified in your pom.xml, and generate a JAR file named after your project in the target folder.
To verify, unzip the JAR file and you should be able to find lwjgl.jar along with any other dependencies in one of the folders.
Hope this will get you started.
EDIT:
Building Your Project
If your target folder remains empty after executing mvn clean install, try include this build plugin configuration in your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
</plugin>
</plugins>
</build>
Related
I have a project A depending on a project B. I downloaded the project B from a git repo, I ran "mvn package" and "mvn install" in project B so I have it in my ~/.m2/repository directory.
I tried packaging project A with the "jar-with-dependencies" and it works perfectly, but I don't want a big jar with all the dependencies.
When I put this:
<dependency>
<groupId>ch.usi.da</groupId>
<artifactId>paxos</artifactId>
<version>trunk</version>
</dependency>
the command "mvn package" works fine but when I try to run it:
java -cp target/basecast-1.0-SNAPSHOT.jar ar.uba.dc.basecast.App
I got an Exception in thread "main" java.lang.NoClassDefFoundError: ch/usi/da/paxos/Util error.
I'm doing this only with maven, not using Eclipse. I want to keep it simple and learn what is happening behind the scenes, maybe Eclipse manage the classpath in a better way but I want to do it without it.
Update: I forgot to mention that this 3rd party project B has a lot of dependencies, so including its .jar file as a "lib" is not my ideal solution. I want to use maven dependencies resolution because everything is installed in my local repository.
If you do not want a fat jar (which can be for many reasons) you must first decide what other mechanism you want to use to provide a way to launch your application. Typically you may create an executable jar with a Class-Path entry pointing to all the artifacts you use, or create a shell script that can do various sanity tricks and then assemble a classpath variable pointing to all the artifacts you use, or - on MacOS - package up an Application. Advanced deployments may include WebStart.
A good solution at your current skill level is to use the appassembler-maven-plugin which has these coordinates:
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
which with a appropriate configuration section can create the scripts you need (on both Unix and Windows), put the artifacts you use in its correct spot, all as a part of your normal Maven build.
See http://www.mojohaus.org/appassembler/appassembler-maven-plugin/assemble-mojo.html
for full instructions.
I have created some supportive java classes for help and speed-up the development. Now I want to build a jar file ( hibernate jar files like that) collecting these java classes. then I can add that jar file to other project and use it.. how can I possible to do that.? or any other suggestions?
you can create a jar file by using the following commands
jar -cvf
here c indicates create, v for verbose & f stands for files to be included inside your jar.
If your class files includes main class you need to include manifest file to mention the main class name.
Note: If you want an standalone executable jar which includes another jar files then you there might be a problem while executing the standalone jar because the added libraries will not be placed in classpath at the time of execution. You can take help of eclipse IDE which will create a jar file which includes the jar file executes successfully.
If you are trying to build a JAR it depends on your IDE.
In Netbeans for example you can run the clean and build command whereafter your JAR will be placed in PROJECT_FOLDER>Dist
If you are using eclipse then try installing fatjar plugin. Once installed then right click on your java project and you can build it as jar. If you need you can include the dependencies too in the result jar.
First Convert your .java file to .class with the command line.
javac ClassName.java
Next, create a JAR file containing the ClassName.class file. Type the following in your command window:
jar cvf ClassName.jar ClassName.class
This creates a JAR file, ClassName.jar, and places the ClassName.class file inside it.
For further reference See the Documentation
You could use maven to bundle your jar, deploy it to a private repo like nexus, then pull down the jar in the second project with maven dependency management. Technically you don't need nexus, you could just build the jar and have it go to your local .m2 repo. Then when the second project gets build it will pull the jar from your local .m2 repo. You can achieve this by running mvn install on the jar project.
Easiest steps
Setup your first project, the jar project, to be built with maven. You will need to setup a pom.xml in the project root. You should also follow a standard folder layout. You don't need to use this layout for maven but it makes things easier. Maven will allow you to override all of these locations in the build element of the pom.xml.
Next search google for how to setup a basic pom.xml. Set your first project to package type jar. Here's an example pom.xml of what it may look like for your jar project. Don't paste the ... they are just there as placeholders because I don't know the details of how you want to build your project.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.your.package.base</groupId>
<artifactId>your-jar-project-name</artifactId>
<packaging>jar</packaging>
<name>your-jar-project-name</name>
<version>1.00</version>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
...
</dependencies>
<build>
...
</build>
</project>
After you have the pom.xml in the root, cd to that directory and run mvn install. This will build the jar and place it in your local .m2 repo. Next you will need to setup a pom.xml in the project that needs the jar project. Insert this in the dependencies section of the project that needs to use the jar.
<dependency>
<groupId>com.your.package.base</groupId>
<artifactId>your-jar-project-name</artifactId>
<version>1.00</version>
</dependency>
Good luck and have fun!
I execute the command: mvn eclipse:eclipse to add the required librairies included in my pom file. The problem is that any source folder are deleted after executing that command.
There is any way to add the libraries without deleting the source folders?
I'm not sure what you are doing exactly but the eclipse plugin handles only eclipse configuration and does not touch any source folders. If the source folders are removed from your eclipse project, then the project/pom file is not set up correctly.
Since Juno, eclipse contains the m2e maven integration plugin. I suggest you create your first projects using that. It will take care of handling the build process and project setup for you.
Use the New->Project...->Maven Project menu and create the project using the wizard. When it is complete, copy all your existing sources into the new one and manipulate the pom file with the pom editor (eclipse will open the pom file with this editor by default.)
Important note: If you start using m2e, then don't use the command line eclipse:eclipse target any more as all the house keeping is done by m2e from that time on. If something is really messes up in your eclipse project, then you may delete the project from the workspace (don't tick the delete from disk option), run eclipse:clean (to make sure everything is cleaned up) and import your project with the m2e importer (File->Import...->Existing Maven Projects...)
As allprog wrote: your source folders are probably not deleted. (but probably removed from your .classpath file)
Maven use a standard configuration for all project. Usually there are 2 source folder (for *.java):
/src/main/java for your production code
/src/test/java for your test code
It's a good practice to follow this recommandations, but you can choose another location for your production/test code by adding this in your pom.xml:
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
...
</build>
Using multiple source folder for your production code and/or for your test code is not recommended.
I created a new Maven project in Eclipse. This was working fine until I needed to add a dependency to another Eclipse project, a legacy utility project, which does not have a pom.xml, and does not have the directory structure of a typical Maven project. (It has the directory structure of a typical eclipse Java project). This other project is in the same Eclipse workspace as the Maven project.
In looking at other posts on this, it seems that usually the solution is to build the jar for the other project and install it in Maven. However I am actively modifying code in the utility project while writing code in the Maven project, so I can't just install a jar once to satisfy the dependency.
What is the easiest way to handle this so that I can code simultaneously in both projects, and also get maven to build cleanly? (Of course Eclipse can build just fine with just a project dependency.)
UPDATE
Using the Build Helper plugin to add the utility projects source folder to my pom was a viable path to the solution, but then I needed to update all the dependencies of the utility project into my new Mavne project, which started to make the whole process too time consuming (and also not really the chain of dependencies I wanted). I think that if I would have added all the dependencies, then Build Helper suggestion would have worked.
For now, I built the utility project jar and installed it into maven. Which turned out to be the the quickest solution. I will try to Mavenize the utility project, without modifying its structure (as suggested by FrVaBe below), and see if I can link the poms afterward.
I am going to keep this question open until I have a full solution which can be reported back, since I assume this is a problem others will have (trying to integrate legacy projects with new maven projects).
For the development time you can add the dependency as a System Dependency. It will be resolved by the file path (which can be the path to your utility.jar file under development) in this case.
It is added as describe in the link above, e.g.:
<dependencies>
<dependency>
<groupId>my-utility</groupId>
<artifactId>my-utility</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${somewhere}/lib/my-utility.jar</systemPath>
</dependency>
</dependencies>
The maven handling of System dependencies is sometimes special. E.g. they will not be included in war-packages! Therefore, when you are finished I would strongly recommend to install your utility library to the maven respository or to deploy it to a repository manager (Nexus/Artifactory).
You can add utility project's src folder to your working project in eclipse. For your development purpose.
right click on Working project
go to properties and choose java build path
go to source tab
Add your utility project src folder to that.
Later you can install your jar as maven dependency.
I use Apache Maven to manage my Java libs (jar) and some of projects that use the libs. For convinience, I use mvn eclipse:eclipse to generate Eclipse project files which can be imported into Eclipse workspace for editing.
Problems arise when I edit the main project and Java lib projects in the same Eclipse workspace. That is, mvn eclipse:eclipse includes src path dependency in .classpath file, not the jar dependency as expected.
Say I have a Jave lib project named mylib. The corresponding jar file mylib.jar has been deployed to a private Maven repo maintained by me. In order to use mylib.jar in the main project, the following dependency is included in pom.xml.
<!-- pom.xml for the main project -->
<dependency>
<groupId>namespace.my</groupId>
<artifactId>mylib</artifactId>
<version>[1.0, )</version>
</dependency>
mvn compile and mvn test work perfect, in which mylib.jar is automatically downloaded from my repo. However, when trying mvn eclipse:eclipse, I find the generated .classpath file doesn't include mylib.jar dependency as expected. Instead, it includes source file directory for mylib as follows.
<!-- .classpath file generated by mvn eclipse:eclipse -->
<classpathentry kind="src" path="/mylib"/>
It seems that Maven reads Eclipse's metadata and finds mylib and the main project coexits in the same workspace. Therefore maven includes the source for my good. Damn. How can I tell maven to ignore the local project source and just include the jar file?
I believe this is actually because they're related projects in Eclipse. So if you right-click on your main project and go to Project References your lib project should be ticked.
If you run mvn eclipse:eclipse it will automatically add project references for any sub-projects (modules). You can change this with the useProjectReferences property of the maven eclipse plugin.
It defaults to true, but
When set to false, the plugin will not create sub-projects and instead
reference those sub-projects using the installed package in the local
repository
To use the property either set the property in your pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<useProjectReferences>false</useProjectReferences>
</configuration>
</plugin>
<plugins>
<build>
Or as a property on the command line:
mvn eclipse:eclipse -Declipse.useProjectReferences=false
I need to avoid to include the dependency as a refrenced project, but as a jar.
Using Eclipse 4.6 Neon none of the previous solutions work.
I had disable the Workspace Resolution feature
click on the project -> Maven -> Disable Workspace Resolution
Thanks for Hound Dog's hints. Yes, useProjectReferences controls Maven how to handle sub projects -- including source dir or including jar files.
I haven't installed the maven plugin for Eclipse, so I add the following configuration in pom.xml. It tells Maven to include jar dependency in local maven repo, not the source dir. If the required jar file is not present in local repo, it will be automatically downloaded on the fly.
<!-- pom.xml for the main project: include jar, not src path -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<useProjectReferences>false</useProjectReferences>
</configuration>
</plugin>
Now mvn eclipse:eclipse works as expected.
Just try using the type element inside dependency tag and mention source/jar as the type in your pom.xml
<!-- pom.xml for the main project -->
<dependency>
<groupId>namespace.my</groupId>
<artifactId>mylib</artifactId>
<version>[1.0, )</version>
<type>jar<type> <!-- source/jar -->
</dependency>
I have recently experienced that this behaviour is triggered by the version stated in the pom.xml files. If the version of the lib your primary project is depending on is available to eclipse in the workspace (e.g. a project with the matching pom.xml [group,artifact,version] for the lib) this will be used as a project reference in stead of being pulled from the M2REPO-location.
My solution was to change the version of the library pom.xml in the workspace to another version allowing me to improve the lib, while the primary project still pulled the older lib from M2REPO.
Using this by aligning the version numbers allows you to perform concurrent artifact improvements/alterations with little hassle.
I have not yet tested if you need to run the mvn eclipse:eclipse every time you change the lib pom.xml files and the primary pom.xml dependencies, but I would expect it to be so.
I tried closing the project in eclipse & the workspace just built itself, this time taking the jar from the repository instead of linking the project