Is platform enforced versioning mechanism most sor

2019-02-17 00:10发布

问题:

As developer, I am often interested in new language feature that can make your life easier. For example, java 5 brought generics and annotations to the language, features that can definitely boost your productivity.

However, when I look back at close to a decade working on java platform, I find that the versioning related problems are the biggest culprit of unproductive and needlessly spent effort. Hours and hours of looking for the correct version of the jar, trying to reconcile some versioning conflict, upgrading dependent libraries etc. When I started working in java, things were not that difficult, you’d have a few 3rd party libraries and that’s it. Today, your typical web app might easily use: Spring Framework, Hibernate, Struts, you name it. All of these carry a number of dependant 3rd party libraries. Today, my ear archives will typically include some 40 or more 3rd party libraries. A real jar hell!

With annotations, I don’t have to manage config files for Hibernate for example. A nice feature, but I haven’t seen that many problems arising from the fact I keep my descriptors in separate file. With generics, I am spared from writing cast statements, but in my whole programming carrier I can’t remember a single bug that could have been prevented by using type-safe container. Wouldn’t solution to versioning problems have been much more valuable?

All these problems have resulted in number of tools like Maven, ivy, One Jar, Jar Jar Links (not kidding!), even appropriately named Jar Hell etc. Even if you use some of these tools, you are far from being immune to the problem. I use Maven 2 and it has been a great help. Still, it is a world to itself. Novice programmer can take a while to learn it. Moving your legacy projects to Maven structure is also a pain.

It seems that in .Net they have learned the lesson with dll hell and management of .Net assemblies is much simpler.

There seems to be plans to solve this problem for java platform and alternatives like OSGI. I think that some basic and platform enforced versioning mechanism is badly needed

回答1:

Take a peek at OSGi - it deals with versioning and management of bundles (jars) very nicely.

ALSO: Eclipse (which is built on top of OSGi) has some relatively new API Tools that can help you compare your API against a previous baseline and determine how to appropriately express the next version number of your bundles.

The general eclipse versioning scheme:

v.m.n.q

where

v: high-level version - changes here represent generally breaking changes in the API

m: major changes - new functionality, new API

n: minor changes - same API, behind-the-scenes changes

q: qualifier - useful to mark builds, alpha/beta, etc

OSGi specifies version dependencies using ranges. For example

Require-Bundle: com.javadude.foo;bundle-version="[1.2.0,2.0.0)"

in your MANIFEST.MF specifies that the bundle requires version 1.2.0 or later of bundle com.javadude.foo, up through (but not including) version 2.0.0.

You can also specify dependencies at the package level instead.



回答2:

I've also been using Java for over a decade but I have to say I haven't found many JAR hell issues at all (even using all the 3rd-party tools you mention)! I found Maven to be a horrible tool, so build everything with ant.

At our company we have a bespoke dependency-resolution ant task based on a simple (small) dependency file for each project, together with defining each project as either an app or a lib (you should only ever depend on a lib; never an app). It works just fine.

We also have ant tasks to modify our eclipse .classpath and IDEA .iml files to generate dependency graphs for our IDEs.



回答3:

The advantage that .NET has over Java is that the libraries are tied more closely to the OS. The fact that the framework libraries, if they are installed, are easily located in the GAC does simplify things, but you're also pretty much limited to Windows. A better comparison would be Mono, but I don't have any experience there.

Configuration management, at least to me, has always been the big pain of software development. The more you try to take advantage of existing code, the worse it seems to become. The problem itself is not unique to Java, but the proliferation of versions, the amount of time the platform has been around, and the number of platforms supported does seem to make it worse. I just checked and I have 3 versions of the JRE on my box right now -- and I'm not even an active Java developer.

As to your question, I'm not sure if it is the most pressing feature need. Personally, I'd like to see some better support for web services, particularly those requiring authentication headers. The last time I tried to get Java to interact with one of my .NET web services, I nearly tore my hair out. Having used LINQ with C#/.Net, I can also say that would be a pretty cool addition to Java with arguably more productivity gains to be had.



回答4:

.NET supports side-by-side assemblies, so you can have multiple versions of the same app arround. The GAC is like shared DLLs, but still you can register multiple versions of the same assembly at the GAC and another assembly can request a certain or a greater-than version if I remember well. In JavaEE you do have several class-loader levels btw and you can do some tricks simulating similar versioning



回答5:

I came across this problem at a site I worked at: built a tool to run through the jar files living on a webserver and find all the nested copies of jar files - and different files with the same names (eg: versions of log4j.jar). It was a hideous mess, including one WAR that had the WebLogic jar inside it.

Not sure what the solution is.

Thing is: java has stuff to manage this - stamped jar files with package versions. And particularly: webstart. Perhaps what's needed is some kind of classloader that does a webstart-type thing.

How about: in the JAR manifest, you specify library dependencies, using well-known names and versions. The classloader - provided by the container or the runtime - would be responsible for getting the versions that you want.

There are plenty of systems (eg: Maven itself) for managing well-known places to download libraries from, as well as fink and whatnot.