How do I prevent IntelliJ from including 3rd-party JARs inside my JAR ?
It's insanely annoying. Basically I want one of these:
to produce jar with my code only. 3rd-party jar will be referenced in manifest.
OR
to produce jar with extracted classes of 3rd-party libraries.
The only problem is that IntelliJ produces JAR with other jar files inside. They are useless because java doesn't see them anyway when I run my jar via java -jar my.jar. I have to manually delete them and repack JAR/ZIP file.
Dependencies are not marked as "Export" in Settings.
I think jars end up in my jar because I added "compile output" in layout of my artifact. But I'm not sure how I can make compile output without jars of dependencies.
I tried setting Scope of dependencies to "Provided". It didn't help. They still get copied to output.
Thanks!
This behavior is controlled by the following options when you create a jar artifact in IDEA:
Refer to help for details.
Related
I recently wanted to decompile a jar and edit the contents, so I used jd-gui to decompile it, I saved the project, and I unzipped it. I opened the project in IntelliJ and I was getting a lot of errors for missing types. All the imports that were not built into Java said unknown. Where are these libraries in the jar, and how do I get them out and add them to intellij?
An application may have dependencies that are not included in the jar at all. In that case, the user would be expected to install the dependencies themselves.
I have read numerous posts regarding this, and I was still not able to find a clear-cut answer.
We have the need to use a proprietary SDK in our maven project and this SDK contains ~315 jar files that are needed for around 30 lines of code (SAP product). Every answer I read dealt with adding individual jars to your local maven repo. That is fine and I understand that, but is it possible to add an entire directory of libraries. These libraries are only needed for compiling the project since they are already on the classpath of the target server (They would all be scoped as provided in a pom).
I've tagged Netbeans 8 since that is the IDE I am using, so if anyone knows a hack to get a maven project in netbeans compiled using libraries on Netbeans classpath that would be a good solution as well...
JAR's are just java .class organized in folders and Zipped. Extract all those 315 JARs to somewhere, thus merging all of their content, and then Zip it again to one single fat JAR file. Add this fat JAR to your local repository as you have read elsewhere.
This other question can help you with the JAR merging thing: How to combine two Jar files
Although there are many messy workarounds for this, the ideal would be to let the compilation fail and search for the missing compile jars using a search utility like agent ransack you can search within the jars in that directory for the missing classes referenced in the compiler errors. As you find the jars you need, add them as dependencies with the scope of provided.
A less clean option would be to zip all of the jars, use the dependency plugin to unpack them to a folder and add that folder to the classpath of the build, then remove them or exclude them from the final package.
So I'm fairly new to Java and especially Eclipse, so please excuse my ignorance. I took a project from a server and copied it locally to my machine. When I opened the workspace, I had many errors due to it not being able to find the jars. This makes sense because I don't have the same dir structure as the server I copied from. So if I copy the same external jar's to my machine and get it to compile into a jar and copy it back to the server, will it work? Or will it fail because now the external jar's are in a different place than it is expecting?
Also, down the road should I put the external jars into regular jars to avoid this problem?
You should be OK. Java is using what is called classpath to locate dependencies. The classpath may be different on the development machines, but as long as all the dependencies are on the classpath in the production everything should work.
To avoid issues with the synchronisation of directory structures the most common way is to use Maven - it will manage all the dependencies for you (but you have to manage the pom.xml - the Maven's project descriptor). A little clumsier way is to have the dependencies in the project, however you may end up with many projects having to include same jars, and then there will be version conflicts and so on.
For small projects you can manage dependencies yourself, however larger projects will need a more thought through strategy (like Maven).
In regard to the executable jars, make sure the Class-Path entry in <jarfile>:\META-INF\MANIFEST.MF is correct, e.g. where it references other jars, those jars are going to be there in the production. For example, assume we have ourjar.jar and assume this is a snippet from its MANIFEST.MF:
Class-Path: lib/myteamjar.jar
It will then be expected that a following directory structure is in place:
lib/myteamjar.jar
ourjar.jar
No, the location of the external jars does not mater. What you want to do is put the external jars on your classpath. How you do it depends on how you are running your java code. If you are running it from the CLI using the java command, it takes the classpath as an argument. If you want your code to build/run in Eclipse, you need to right click on your project, select "Build Path" > "Configure Build Path..." Use the "Add JARs..." button to add jars that are part of a project you have open and "Add External JARs..." to add jars that reside outside of the project. See specific documentation for your tool for more details about classpaths.
I would not recommend Maven to somebody who is fairly new to Java and Eclipse. I would forget about Eclipse, too.
You have a packaging and CLASSPATH issue. Focus on that.
What kind of project are you talking about? The answer you get will depend on what type of app you're creating. Is it an executable JAR? Then the right way to do it is to package everything into a ZIP file that's laid out exactly as the CLASSPATH in the JAR manifest expects.
If it's a web app, the right thing is a WAR file, with all the JARs your app needs in the WEB-INF/lib directory.
If you package things properly, you should end up with a single package that has everything laid out the right way. You should be able to deploy it to the server and make it all work.
I've created a simple plugin project in eclipse 3.5 that just stores third-party libraries for the use by other bundles in an eclipse RCP application. Worked as expected: I edited the manifest, exported the required packages and added the libraries to the build path (project build path as well as manifest build path).
Some days later I added another jar to that project, did the same steps (exporting a package, adding the library to the build path(s)) but this time I can't import classes from that exported package in other bundles. The package was clearly selectable on the manifest editor but import statements in classes just taunt me with curly red lines. Importing classes from other packages exported by the bundles still works, only classes from the newly added lib remain invisible.
Has anyone has an idea what I might have missed? I'm pretty stuck and have no idea how to convince google to show me the solution to that ugly issue...
Check the following:
Make sure they are in the Build
Configuration -> Order and Export
area, and they are check for export.
Make sure you have the packages
exported in the manifest (PDE Tools
-> Open Manifest -> Runtime tab)
In the same place as above, make
sure the JAR files are in the
manifest classpath.
(as Al says
below), make sure the build
properties has your jars marked for
exclusion (though this is not likely
your issue as you are getting errors
compiling).
If all of this is done (and it's still not working), do a clean build an restart eclipse. Sometimes the Eclipse gets a little confused about this and a restart helps.
Check the build.properties to see if the bin.includes includes your newly added Jar. Without it, it won't be exported by the build process, and thus won't be able to use it in dependent bundles.
I am using Netbeans IDE for a java project. In this project i need a jar file "htmlunit-2.6.jar".
I have included this jar file in the project libraries folder. I have instantiated one of its class "WebClient" but this class needs other classes of "commons-httpclient-3.1.jar" file.
Now I have also included "commons-httpclient-3.1.jar" file in the project libraries folder. But when I compiled my source file, it throws
ClassNotFoundException: org.apache.commons.httpclient.auth.CredentialsProvider
Kindly tell me how to handle this situation when one class in one jar file needs other classes in other jar file.
Simply put the required jar files on the classpath at compile-time and it should work. If you were doing it from the command-line then it would look like this:
javac -cp jar1:jar2 my.Application
If you are using NetBeans then you need to tell NetBeans that both of the JARs are on your classpath. It will be definable in a Project > Properties wizard as described here and also here from the tutorial
The ClassNotFoundException tells you that your libraries have some dependencies that you don't have included in your classpath at runtime. Your source is OK, because if you have used something not available, NB will tell you this at compile time (or before when editing).
So, welcome in the "dependency hell" of Java. For small projects you will be able to check all dependencies by hand with readme files, docs, etc and put them in the project config as oxbow_lakes said. For bigger things look at maven. It will do (most) everything for you !
(Maven is available in NB6)