I have a web app with thousands classes packed in hundred jar's placed in several folders.
I want create in local maven repository a library, containing all classes from those jars.
And I can use this dependensy in all my projects...
Like in a IntelliJ IDEA i create a global library. Select a folder with sets of jars with subfolders and set name "My web-app libs". And then i add this global lib on my project.
I have founded a way for construct group for several libraries, described here. But I have a hundred jar files and stupid make new project for each.
In advance thanks.
Look at maven shade plugin.
This plugin provides the capability to package the artifact in an uber-jar,
You may want to create another project which enlists all your artifacts as dependencies. So when you include it into your project all the needed 100 dependencies will be transitively resolved.
Maven Versions plugin could help you bulk updating the many versions inside this new artifact.
UPDATE
If all your 300+ jars are completely static, i.e. their versions are fixed, you might probably need to repack them with the shade plugin. Otherwise updating a version of a JAR from this huge set could be a trouble... I can't predict the performance, but my guess is that a normal Maven approach is more efficient.
A note on Maven shade plugin: you might need to move your shaded libraries to shaded package. That's what they usually do to avoid library versions conflicts. I.e. if your 300+ libs use spring-2.0 and your current project uses spring-3.1.0, both will be included anyway. So to avoid conflicts, it's recommended to configure this plugin to move spring-2.0 packages under a different package.
UPDATE 2
If your jars are not mavenized, Maven won't be a big help here. You should probably merge your jars manually and check if it works for you: Merging Multiple Jars in to a Single Jar.
Related
I am trying to add a dependency as jar file and that jar is shipped with all the classes which are needed for it to run.
compile files('lib/org.hl7.fhir.igpublisher.jar')
Along with that, I have few other dependencies which are added as maven dependencies.
compile ("ca.uhn.hapi.fhir:hapi-fhir-base:2.3")
Now I am facing a lot of issues related to class conflicts because same classes have been shipped with different versions.
In an ideal case, how should I solve this problem? I want to say that the local jar should always use its own files and other dependencies should ignore the local jar files.
Note:- I am using IntelliJ idea.
This is a tricky problem. There is only one classpath and multiple versions of the same class mean that only one of that versions is visible and the other ones are hidden.
One should generally avoid to declare dependencies on "fat jars" that contain their own dependencies. If possible, one should use the slim version without the dependencies (often both versions are published). If there is not alternative one can construct such a slim jar yourself by manually splitting up the jar file. It is also possible to control the structure by carefully ordering the dependencies on the classpath, but this is a little brittle.
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.
I am using Maven and my configuration (which is most likely the default) produces this:
That means my compiled code is 4% of the file. Largest inflation was caused by the GitHub API library - I am strongly considering that I'll just drop it.
But my question is about the small file, not the big one. Maven creates it for a reason right? Could I maybe somehow distribute it and have it work on clients' computers? Why does it exist and what useful can be done with that?
Given your question, your Maven project is most likely a jar project that uses the maven-assembly-plugin to generate an uber-jar. In your output, there are 2 different files that are the result of 2 completely different process.
autoclient-3.0.jar is what's called the main artifact. This is the primary result of the Maven build. It consists of the compiled classes in your project alone, packaged into a jar by the maven-jar-plugin. You have this file because your project has the jar packaging. In Maven, the jar packaging automatically bind goals to build phases of the default lifecycle: among others, it includes an invocation of the jar:jar goal, which creates this main JAR. But you have to realize that this JAR only contains your classes. If you try to run the code, it will probably fail because the dependencies won't be there. What's its purpose if you can't run it then? Well, its purpose is to serve as a library for other projects, not as executable code.
Take, for example, a utility library that you would like to create: this library is not intended to be ran directly, it's intended to be used as a dependency for another project which will be executable. With the notion of transitive dependencies, Maven will automatically include in the buildpath of the other project your library and all its transitive dependencies. As such, your library does not need to embed its dependencies directly: they will be resolved correctly during the build of the other project.
autoclient-3.0-jar-with-dependencies.jar is what's called an additional artifact. jar-with-dependencies is a classifier that is used to distinguish this artifact from the main one. It is the result of the execution of the maven-assembly-plugin with the predefined jar-with-dependencies descriptor file. This artifact consists of the compiled classes of your project and all the direct and transitive dependencies of your project. An uber-jar (or fat jar) is really that: it aggregates all the dependencies and your code inside one big jar. The advantage is that you don't need to distribute separately the dependencies, they are already included in the JAR. But do note that its purpose is not to serve as a library, it is to be used as executable code.
Note that for a single project, it could make sense to keep both JAR: one intended to be used as a library (the main JAR) and the other intended to be used as runnable JAR.
I have a single very large codebase that compiles down to a JAR. I also use the shade plugin to compile it down and package it up with all dependencies. I also use the war plugin to get a WAR file.
With respect to the WAR file, once the goal is created I have a post-build event that simply copies the WAR file to its destination, so technically I'm good with that.
The problem I have is with the other two JARs. They both share the same artifactId since they're both built in a single pom.xml and this isn't acceptable for a number of reasons (including, but not limited to the fact that some caching of dependencies is pretty dumb about realizing that one JAR is the thin one and one is the full-dependency one).
What I need to do is create a pom.xml (or group thereof) suitable for builds (by Jenkins) that can use the same codebase (pulled from Github) but create two separate JAR files, each with their own artifactId.
Being a Maven novice, I've read through the beginning book and it seems to me that what I want is a parent pom.xml with two modules. But from what I can tell, each module means a separate directory with separate code. As I said, this is built from the same codebase. The only difference is one is built from the "regular" build, and the other is built using the "shade" plugin and goal.
The only other thing I can think of is build the "regular" JAR and then build the shaded JAR with a classifier of "full?" If this is the answer, may I humbly ask for some adult supervision on how to do this, as I'm not seeing how.
If that's not the answer, I suspect this must be a common problem, so again, some guidance would be very helpful!
The solution I came up with was to use a classifier for the "shaded" jar. Thus, the artifacts don't collide.
I then had an issue accessing it, but found the solution to that issue as well - How do I access a jar with a classifier?
I've got an Android project that has multiple modules. These are all Git submodules, and several of them are packaged with the same jars (android support v4, Guice, Roboguice, etc.). My main project also has these same dependencies, so I've got three copies of these jars, one in my project, and one in each of two submodules.
When I build, it fails at the dex stage, complaining that certain classes have already been added. I can hack around this, by getting rid of the jars from all the modules, except one, then pointing the dependencies to that location, but it just feels so dirty. There's got to be a better way. Any suggestions?
Use a build tool like Maven or Ivy that manages dependencies for you, so you don't have to check JARs into your project.
Are you using Eclipse ADT? If so this problem has been solved with the latest ADT. The old one used to have the problem you are describing but the new one should work.
Check this link out for details:
http://tools.android.com/recent/dealingwithdependenciesinandroidprojects