I am trying to add an external library to my Java project. The library files are in .jar format, and every time someone tries to run the project in a different environment, they have to modify the build path so that their environment can find the .jar files.
Is there any way to make it so that the .jar files are automatically found by the build path? Maybe by specifying where in the project the .jar files are located?
Edit: Here is an example -
In my linux environment, the .jar files are located in:
/home/MyUsername\SomeDirectory\workspace\java_project_name\data
In my windows environment, the .jar files are located in:
C:\MyUsername\SomeDirectory\workspace\java_project_name\data
In the example above, the project root directory is "java_project_name", and the .jar files are always in the java_project_name\data folder. Even though this is the case, different environments can't seem to detect that it is always in the same path in relation to the project's root directory.
I have looked in many places on how to do this, and some people told me it isn't possible. This doesn't sound reasonable to me, which is why I am posting this question here.
Thanks in advance for your help!
you can add a ClassPath: entry in your manifest file of the main jar, and use relative paths. As long as the jars are found relative to the main jar it will work.
This issue was one of my main motivators to start using maven.
#YoK nicely quotes here the relevant reasons to this question https://stackoverflow.com/a/3589930/1493954
Here is one the relevant quotes from Benefits of using Maven
Henning
quick project setup, no complicated build.xml files, just a POM and go
all developers in a project use the same jar dependencies due to
centralized POM.
getting a number of reports and metrics for a project
"for free"
reduce the size of source distributions, because jars can
be pulled from a central location
This is a common problem for developement environments.
I myself use the following solution in netbeans [Hope so that it works in your IDE too]:
Create an Ant variable [for e.g. JAR_LOCATION].
Each and every JAR that you refer, must have it's location relative to JAR_LOCATION.
Now, in every development environment that you're gonna use, you can set up the same ANT variable and it'll automatically pick up the JAR.
You can see the example in the given snapshot of netbeans..
Related
I am making a java web application that a hosting service is running for me, and I must recompile and send it to the host every time I make a change. I would like to be able to put all of my libraries in a folder in the host, and only have to compile my jar that will know that its dependencies are next to it.
I have used the IntelliJ IDEA builder located in File > Project Structure. I export all library jars used in a folder next to the main jar named lib, and I have learned about wildcards so I set the classpath to be \lib\*. This did not work and I was thrown a chunky NoClassDefFoundError in my server's console.
I know this must be possible. How should I change my approach?
EDIT: I have researched a bit deeper, and the answer to this question states at the bottom that the wildcard system is not honored in the jar manifest attribute. Do I have to include all files individually (And if so, how?) ?
I hope somebody can help me with my problem. After hours of scanning all different posts concerning the abovementioned topic I now decided to answer my own question. None of the other posts solved my problem.
I want to export an existing JAVA project as runnable JAR. Therefore I'm changing all absolute references to the following:
this.getClass().getResource("/somekindofimage.png").toString();
This way I can reach all available files in the runnable JAR.
However I need to reference a folder...so I tried it the same way:
this.getClass().getResource("/somekindoffolder").toString();
which gives me the following path:
file:\C:\Users\...\1_data_collection
By creating a file and checking with "is.Directory" it returns false.
I unzipped the runnable JAR. All folders, all files that are needed are included. They are attached as sources via BuildPath.
When I test the abovementioned path with Windows Explorer it directs me to the folder I'm looking for.
I'm using Eclipse Neon 2 as IDE, my JAVA Version is 1.8-0_144.
Thanks in advance!
You can't refer to files in a JAR using a File path. You have to load them as resources from the classpath.
Make sure the resources and dependencies you need are packaged in the JAR. There's a Maven Shade plugin, if you're using Maven, that will do it for you.
I am using JetBrains IntelliJ IDEA IDE. This is what I used to generate the jar file. Running the jar file from the IDE, everything looks fine.
Running the jar from the terminal, none of the images are loaded.
My feeling is, from reading around on this, that this has something to do with the relative paths used for the images... but I can't figure this out. I've tried various different project folder structures suggested on the JetBrains forums and StackOverflow, to no avail. Everything is fine until I run a jar outside of the IDE.
My current project structure:
How on Earth do I create a jar file that works everywhere?
Ok, so here's what worked for me. I opened the project structure window (Ctrl-Alt-Shift + S) and went to the Modules tab. From there, I could easily select a folder from the list and click to make it a Resource directory. I was then able to access the resources as URL's with
URL imageUrl = ClassLoader.getSystemResource("image.png")
No need to use a path to the image, just it's actual name.ext
Using IntelliJ's resource folders is probably the right way to go.
Simply right click your res folder, go to Mark Directory As and select Resources.
Then you can access files in this folder simply by name (without a res/ prefix.)
Working visual example:
Source and Resource roots are handled differently.
All the files from the Resource directories will be always copied to the output path. As suggested in another answer, one of the solutions is to configure this directory as Resources root. It's the preferred way to get it working.
If you want files from the Source roots to be copied to the output, you have to specify the patterns for the files that will be copied.
If the project is Maven or Gradle based, these patterns have no effect and IDE will use the rules of the corresponding build system to process the resources.
Alright, so I have a web service that was created using an eclipse dynamic web project. It is currently shared on a CVS repository, but the versioning system used is irrelevant. At the moment, I have literally NEVER been able to pull this project out as is and get it working. It leads to countless errors that cannot be fixed. Every time I need to work on this webservice in a new machine I have to create an entirely new dynamic project, copy over the source files, add all the necessary libraries and make the deployment assembly work correctly again. After finally making it run I share the project as the same one, stop after a second, and then synchronize again (in a way tricking eclipse into thinking this was the shared project all along).
I feel like others must have run into this problem and found a way around it. So if you have a web service or any dynamic web project, what files do you share, and how do you successfully pull it from the repository and get it to run on another machine besides what I currently do now?
Your help is much appreciated,
-Asaf
Edit: After reading some of the responses I feel that this question is actually more specific to those who use WTP to create/test their web services. Just wanted to add the clarification.
Edit2: Let me also clarify that the other 20 or so projects not using WTP are shared just fine. I am able to pull and run them with no problem. Only web service projects are an issue.
In general, you want to check in everything that's not "derived" (generated or compiled - that's usually the contents of the bin directory or other place where your code is compiled/built into). For Eclipse Java projects, you want to include the .project, .classpath, .settings, and any other similar files that Web Tools might create for Dynamic Web projects. The Eclipse CVS client will ignore files marked as Derived so you shouldn't have to worry to much about it.
Without more detail about what kind of problems you've run into, it's not possible to guess what was causing them. My only guess is that perhaps you had different versions of Eclipse and/or the WTP (Web Tools Platform) plugins installed on the different machine. That's just a wild guess, but could explain some incompatibility when you check out the project from CVS.
Bottom line, checking in those .* files is the long recommended approach from Eclipse gurus. Maven can kind of change things, but you didn't mention it so I'm assuming you aren't using it.
I am primarily sharing my experience, may be you can find some help.
Conceptually speaking, the files which the IDE can generate itself while creating new project should not be pushed. I.e the IDE specific files should not be pushed. And everything which the IDE cannot generate on its own must be pushed.
Forexample in case of eclipse, following files should not be pushed:
.settings
build
.classpath
.project
For setting the project on new machine, first pull the files from server, and then create a project from IDE using pulled files.
EDIT: If your project has external jars/libraries, then you will have to add to the classpath manually. You could also push .classpath but that might give errors while creating a new project.
I think it's easiest to use a build system and let the IDE generate the project from your build system.
Eclipse, Netbeans, and Intellij are all pretty good at building projects from maven or ant build files. With this solution you have a simple build that is easy to setup in CI (Hudson, Bamboo, whatever) and you don't have any IDE specific files checked in. If my workspace is totally different than yours, with different versions, plugins, whatever, I'm not stuck with your project file and you're not stuck with mine. My IDE creates the project appropriate for my environment and your IDE does the same for yours.
Since you mentioned having to manually add libraries, I assume you are not using any build manager (like, maven or ant) besides ecplise.
For ecplise to handle the project properly you need the source files (*.java) in their respective directories, any resources bundled with the web service (e.g. services.xml), the ".project", ".classpath", ".settings", etc. files for eclipse. This should be enough for eclipse to generate anything else necessary to build the project.
Any files/directories that are generated by eclipse during the build process (e.g. target & bin directory, *.class, *.war) should not be checked in -- they will be generated when needed during the build.
I am thinking that, since you are adding the necessary 3rd-party jars manually, these libraries might reside in a different path between computers (e.g. if the path contains the username, it will not be transferable to another computer for a different user). To fix that you can set up the classpath using an eclipse classpath variable. In Preferences->Java->Build Path->Classpath Variables set up a varable linked to the "root" folder where the 3rd party jars a stored. Then add the libraries to the project using this new variable, not their full path. To make it work on someone else's computer, you would only need to set this classpath variable to have the build path point to the correct libraries.
It might be beneficial if you migrated your project from eclipse only to a build manager (e.g. maven) that takes care of many of these issues for you. Eclipse can build a project from the configuration of the build manager, making it easier to manage the project.
I'm porting a few java gwt projects into eclipse and the projects depends on many external .jar files, some of the dependencies seem to be dynamically linked so eclipse isn't picking up the missing links while running the ide.
At run time, I often get exceptions that say for example 'import bar.foo.XML' is missing or some FooBar class definition is missing and it always takes me a while to figure out which .jar file these classes/libraries belong to so I can add them to the run path.
Is there a quick way to search which .jar files contain what classes and what other library they depend on?
An oldie, but still good, and integrated into eclipse:
JarClassFinder:
Update 2013: the project still exists in a different form as an independent app JarClassFinder.
In term of Eclipse plugin, it is no longer maintained, and you only have variant like "BundleclassFinder".
Other (manual) ways to find a class within jars: "Java: How do I know which jar file to use given a class name?"
You need a tool like Jar Analyzer
Can't you just mark all the jar-files in Eclipse and right-click->add to Build Path?