Trying to build Spring-based application one needs to figure out all necessary dependencies the application will have.
For example, I was using HibernateTemplate, and each time I run the application the ClassNotFound exception comes out. So I “google” for jars that contains this particular class, after search mvnrepository to find appropriate artifact. Always confuse about which version to use.
And it’s happened again and again, and only after few hours and few dozens of dependencies added the application become runnable.
But even after that, I tried to use my app. on different computer with slightly different parameters, and slf4j class not found error appeared, even after testing extensively on the developer machine, still some dependencies missing.
Now it works fine, but I want to distribute my application, and not sure if on another system there will no dependency missing.
So, what is the best practice to determine all necessary dependencies not only at design time but in runtime too? Is there any tool for that?
How one can manage versions confusion, when there are dozens of dependencies each with its own version?
They both resolve dependencies, so you keep a dependency file and it does all the heavy lifting of making sure everything is included in your builds. Use the full spring dependency list. I had problems with SLF4J too.
http://mvnrepository.com/artifact/org.springframework/spring-full/1.2.8
Related
I sure am not the first person to wonder, yet it is really hard to find information on my question.
At the company I work at, the servers run WebSphere 8.5. In order to cut down installation time and memory usage, we created some shared libraries, where we have copy-pasted the common dependencies of our applications. Now you can see, that these can easily cause big problems when changing versions.
We have a Nexus Repository however, where every dependency our applications use can be reached. Since in our gradle projects, we have those dependencies listed anyway, it only seems logical for WAS to download and put these dependencies on the classpath of the application at startup (or whenever it wants to).
Is there a way to tell WAS where to look for these dependencies (our repo server) and what files to download? Is there a better solution to the problem?
There's no way to do this inside of the server at runtime. The best you can hope for is setting up the shared libraries during your deployment, single-sourced with your applications declared dependencies.
We're currently developing a Grails plugin that is meant to be a shared library of goodies for several different applications. This plug-in does the management around GORM and caching and, as such, it includes both the hibernate plug-in and the cache and cache-ehcache plugins. Hibernate and cache-ehcache plug-ins both want to import the ehcache-core jar dependency, but with different versions. The version of ehcache-core that I want is the one in the cache-ehcache plug-in so I've configured my BuildConfig.groovy like so:
compile(':hibernate:3.6.10.10', { excludes 'ehcache-core' })
compile ':cache:1.1.8'
compile ":cache-ehcache:1.0.4"
When running tests in this plug-in everything works just fine. However, once I include this plug-in in one of my real applications the excludes directive seems to be ignored and the transitive dependency on the hibernate plug-in starts pulling in ehcache-core. Having two versions of ehcache-core breaks many different aspects.
I've checked the grails dependency-report for my applications and it shows the chain of dependencies from my app -> my utility plugin -> hibernate plugin -> ehcache-core intact. The same dependency report run on the plug-in itself just points to the hibernate plug-in and then stops with no dependency on ehcache-core.
Anyone out there have any ideas as to why the dependency exclusion works while running the plug-in, but not while running the application that depends on the plug-in?
This is due to the change to the Maven/Aether dependency manager library. It's somewhat less buggy than Ivy and significantly faster, but is missing a lot of features that many of us are used to. One easy fix is to switch back to the Ivy resolver. You would only need to do that for the plugings when publishing, but not necessarily when using them since you need a defailed .pom file with exclusions listed so the consuming dependency manager knows what to ignore. If you use Aether the .pom files only include dependencies.
EDIT: I was focusing on the correctness of the pom files, and or course exclusions like this should work (although it'd be better to have correct poms and not have to force every user to fix this on their end.)
The issue might be that your group or name are different (e.g, "cache" vs. "ehcache"), and then they cant evict/exclude another. Or the jar might be coming from a different dependency and they exclusions are not global. There may be a way to set a global exclusion, but I don't know of one and there's nothing in the docs.
I have a GWT webapp split into two Maven projects where one is a dependency to the other. Each time I change something in the dependency and I'm running webapp in hosted mode I have to rebuild the subproject and restart hosted mode for changes to apply. It takes a lot of time so I'd like to ask you if there is any way to make GWT using "live" version of the dependency?
There are 2 cases:
for server-side code, assuming you use the DevMode's embedded server, rebuilding the app and then refreshing the server should be enough
for client-side code, AFAICT, you have to use the source and output directories of the dependency module rather than the JAR containing them (GWT will load the source from the classpath, but apparently it'll only see the modified sources if it comes from a folder rather than a JAR; at least that's what I found in my tests). This goes against The Maven Way™ but the only solution so far is to use a special profile that will import the sources of the dependency project as sources of the project you're running. You can see examples of that in my archetypes.
There's actually a bug opened for the gwt-maven-plugin, MGWT-332, to do that automatically when running a reactor build. I also mused about what's really needed, for the forthcoming official gwt-maven-plugin (rewritten from scratch, independent from the CodeHaus Mojo plugin).
If your dependency does not come from a reactor build, then you're out on your own: you chose to make it totally distinct, so that's how it'll behave: you'll have to release it (even a snapshot) each time you make a change to it, and use the new version in your app (which means re-launching the DevMode).
This can be circumvented by running DevMode on your own, without the help of the gwt-maven-plugin. You're left on your own managing the classpath though (using the Google Plugin for Eclipse, I suppose you could simply edit the launch configuration to add the source folders of your dependency project to the classpath, before the classpath provided by Maven, that would reference the JAR).
Remove the dependent other application jar file from the primary application lib folder under webapp.
Eclipse should then resolve the dependency using the other project in the workspace if you have added it to your primary application classpath.
As GWT build takes ages, we invested some money in a JRebel license. We have two separate Eclipse projects for our back-end and our GWT front-end. JRebel reloads the classes automatically and I never need to restart my local server while writing code. It proved to be a wonderful time saver. Definitely worth the investment.
I'm working in a big project with lots of modules (they are portlets), and dependency management is becoming harder and harder. We have problems like that some jars are used by all portlets and still not provided for the server, so we are including them in every WEB-INF/lib, or dependencies are declared but not used at all, and stuff like that.
I'm trying to clean up that mess, but I'm afraid of making a mistake and not detecting it until it is too late.
Lets say I mark a dependency as "provided", and it is needed in a strange business case I forgot to test, and the server does not provide such a dependency.
Organization is bureaucratic, and I can not access the server to check the actual presence of a given jar.
Is there any way I can make the a check for dependencies once the war is installed, and see if everything is there and accessible?
War files contain a copy of pom.xml in META-INF, so at least part of the information is there.
I would love to see something like
INFO: Checking provided dependency org.drools-drools-core-4.0.7........done
ERROR: Checking provided dependency org.drools-drools-compiler-4.0.7........FAIL
in the logs...
There is no such tool since all things you're talking about happen in run-time. You'll have to trace all ClassNotFoundException logs and find artifacts that cointain given classes, e.g. using GrepCode. That's the best I figured out some time ago having similar case. Far more easy is to check if you have some declared and unused dependencies or undeclared and used (as transitives) by doing mvn dependency:analyze. It usually works pretty well, but be aware it uses Maven 2 dependency resolution, so it can lie sometimes when using Maven 3. From my experience, it doesn't happen very often, but sometimes it does and causes some problems though.
There are two main approaches when developing an OSGi application with Maven: POM-first and MANIFEST first.
I'm looking for an answer that is in a form of a table that shows pros and cons of each method.
To be more specific, I would also like to know how it relates to:
Maturity of toolset
Vendor independence
Development ease (which includes finding people who can do the development on the tooling)
Compatibility
Avoiding ClassNotFound
Avoiding manual work
At present this is what I can come up with
POM-First Pros (using maven-bundle-plugin)
Leverages existing Maven skills, repositories and tooling.
Likely easier to find people who know how to manage pom.xml rather than MANIFEST.MF along with pom.xml
Most of the information in MANIFEST.MF can be obtained from the pom.xml itself.
Can work with other IDEs not just Eclipse based ones.
Less invasive, just add the single plugin and change the packaging type to "bundle"
POM-First Cons
ClassNotFoundException more likely to occur at runtime. However, this can be mitigated using pax-exam (although it is very complicated to set up).
Still need to understand how the MANIFEST is setup to make sure the instructions configuration element is set correctly.
MANIFEST-first Pros (using tycho-maven-plugin)
Seems to be the recommended approach, or at least talked about as the recommended approach, but I can't really see why it has significant benefit. (Hence why this question was asked).
Good for developing Eclipse plugins and integrates well with PDE
Provides tooling for testing thus allowing ClassNotFoundException to appear during JUnit testing rather than runtime.
MANIFEST-first Cons
Seems to only work well on Eclipse based IDEs. You don't have to use Eclipse, but without the PDE would you want to?
Violates DRY principles since I have to do put keep the names and versions from the POM and MANIFEST.MF in sync.
Need to name things in a specific fashion
You cannot mix, meaning existing Maven multi-project installations cannot just tack on OSGi support
A lot more configuration compared to maven-bundle-plugin is needed to get less warnings: http://wiki.eclipse.org/Tycho/Reference_Card#Examplary_parent_POM
Have to make test cases a separate project. It won't run when built in src/test/java.
Seems that it will only test classes that are exposed, in other words those in ".internal." is not testable.
If I were asked for a recommendation for an enterprise that is using Maven already and want to move to OSGi then it would be POM first
If I were asked for a recommendation for someone who is doing Eclipse plugin development, then it is Manifest first -- with tycho
I think you should choose by use case. For server side OSGi projects I favour the pom first style. It nicely matches the maven builds and is much less error prone than Manifest first.
In fact bnd which is behind the maven bundle plugin gets the Manifest right for most cases without any additional config. The trick is to use some naming rules. For example if you name internal package impl or internal the will not be exported. Using this style you can not use the Eclipse plugin perspective (at least without bndtools which I do not like) but I did not yet miss this perspective. I am a developer in the Apache Karaf, CXF and Camel projects where we use this style and it works great. Especially for CXF and Camel it is great that we can support OSGi and non OSGi deployments with the same build and tools.
For Eclipse RCP applications Manifest first is the way to go as you need the plugin perspective and the Eclipse IDE tools. If you want to combine that with maven then tycho is probably the way to go.
MANIFEST first does not lock you to Eclipse (although I'd be surprised if more than a tiny minority would use anything else). The MANIFEST is the file that counts, and needs to be added to a jar, regardless how you do that.
On the other hand, POM first completely locks you to Maven, you lose the advantage that an OSGi bundle is a regular jar you can make any way you want.
I've tried both, I really prefer MANIFEST first. The MANIFEST file is a really important file, I prefer to craft that file over crafting a file that produces that file. If something weird happens, (and it will at some point) the MANIFEST file is the first to check, it's just easier if it's your own file. Besides, you will have to be familiar with it anyway.
So, if Maven is your alpha and omega, POM first will suit you best, but you'll still need to have in-depth understanding of the MANIFEST file.