Reputation: 25269
I have a bunch of top level packages that are owned by the same team. All top level packages use spring. Then there are some libraries (jars) that are shared functionality and utilities between the top level packages. All pretty standard stuff.
In some cases it makes sense to make use of spring in a library package. Let's say I have a series of Aspects that are shared and I want to use spring's @Aspect/@Before/@After etc. annotations.
The problem is that there are fairly large top-level packages that are written with spring 2.5.6 dependencies, and the newer top-level packages are being created in spring 3. I generally think this is a good thing.
But then there's this little problem that I now have libraries that depend on spring-2.5.6, and those can't be used by spring-3 top level packages because of the mis-matching versions (I'm making the assumption here that sucking in two different spring versions is a very bad idea). It seems that my options are to avoid spring dependencies in libraries, or to accept that my libraries will need to provide multiple versions (1 for each version of spring used at the top package level). Option 1 seems preferable to option 2, but I'm hoping there's some interesting trick that gives me the best of both worlds.
If there was java standards for some of these things (@Inject?) then I could depend on the javax stuff and not on the spring specific stuff. Unfortunately @Inject etc. is only supported for spring 3+ so that fixes my problem at some future point but as long as I have 2.5.6 apps it doesn't help.
Ideas?
I should note that there are some existing libraries that depend on spring-2.5.6 and I view that as a deterrent to upgrading the top level package to spring-3. Because upgrading the top level package means also version bumping N libraries that depend on spring, which is annoying, given that I'm not even aware of the complete set of consumers of these libraries and what they might think of the spring version suddenly being bumped.
EDIT:
I'm wondering if I can create some library, and make a spring dependency with scope of provided. The spring version would be the minimum version that I can pick to get the feature set I want, so ideally I'd use 2.5.6 to make it compatible with a spring 2.5.6 app and a spring-3.0.5 app. Then when a consuming app creates a dependency on my library, it will also create a spring dependency for the real spring version in effect for that application. I'm thinking this should work, so long as the spring version is >= the version I pick for my library (and I happen to know that 2.5.6 is the lowest version in use for all apps).
My other option is to not create a spring dependency at all but DO provide a spring.xml that can be imported in the calling app. This means I can't use annotations or stuff like InitializingBean, but generally spring has provided a way to do things via annotation, or xml, or both, so this should work as well.
Thoughts?
Upvotes: 2
Views: 321
Reputation: 425
As you rightly mentioned, having both 2.5.6 and 3.0 Spring dependencies will create problems. Only one version will be picked up at runtime which means either your top level packaged modules will fail or the other shared utilities will fail (depending on the version of Spring).
A similar issue was discussed in Java Classloader - how to reference different versions of a jar. It is not directly related to Spring but I cannot think of a direct solution to your problem. OSGi is a possible solution but not sure how feasible it is in your environment since it requires change in the container itself.
Upvotes: 2
Reputation: 298898
a) @Aspect
@Before
@After
: These annotations are all in aspectjrt.jar, not Spring itself. They should work with either version
b) @Inject
won't work but @Autowired
will.
Upvotes: 0