Is Apache Commons projects tied with Java edition? - java

I have a question about Apache Commons projects. We know there are many nice classes and methods are available in Apache Commons Projects. But it is related to particular Java edition, I think. If I start use Apache Commons projects now, when Java updates itself to 1.8, I have to make sure Apache Commons projects has the similar update before I update to Java version 1.8? Having some 3rdparty libs is a good thing but I always worry about the compatibility between them and the main programming language I am using.

In general Java is fully backwards compatible, so if you start using e.g. commons-io in JSE1.6 it's going to work in JSE1.8 as well. Working with Java since 1999 I've never seen any issues regarding backwards compatibility.
EDIT: As long as Oracle does not change its compatibility policy, you should not run into trouble. If you later run into trouble anyway, you still have the source to fix it on your own (but may have to give back to the community depending on the license).

The Apache Commons projects update a lot more often than the JDK does. I would strongly advise to keep you libraries current. Even if only to get the newest fixes. That will also take care of any possible problems with JDK versions (which are backwards-compatible and have changed very little over the years and could be considered rather stable).

But it is related to particular Java edition, I think.
The only case where I have ever seen this be true with Apache Commons, Jakarta Anything or Spring was when one version used new JVM and/or compiler features. For example, Spring 2.5 had several jars which were for 1.5 and newer which means that in theory they would work on Java 5 through Java 8 without any bugs caused by the platform. You just couldn't use them on a Java 3 or 4 VM.
This is pretty much the norm throughout the Java community, for SE anyway. JavaEE compatibility may break because it's a matter of library compatibility and development methodology.

Related

When Does The JDK Compile Version Matter?

I have two Java artifacts being built. One needs to be built in 1.6, because PowerMock isn't compatible w/ 1.7 and we are using it in a lot of unit tests. Refactoring PowerMock out right now isn't an option as it will take too much time.
However, I want to use this artifact in a Java application built in 1.7 and run the whole thing in 1.7. I think that it should be Ok since it is just building some class files, which I doubt changed much if any probably as far back as 1.2 or earlier. Anyway, I obviously have a fuzzy understanding of this and I am interested to get a Java experts deep dive explanation as to when this would matter, when it wouldn't, and why.
Thanks!
Java is usually backwards compatible between versions so anything compiled on an old version should run fine on a newer JVM. In fact a lot of common libraries are compiled in as old a version as possible (usually Java 5 now a days) unless they need a newer feature to allow more people who are still stuck on old JVMs.
Having said that, there are a few gotchas you need to worry about. One problem I had on some Java 6 to 7 conversion was TreeMap with an initial value of null http://hariharanselvarajan-java.blogspot.com/2013/02/treemap-in-java-6-and-java-7.html
EDIT
Here is a link to Oracle discussing what isn't compatible between 6 and 7 although I would imagine this only affects things that are recompiled: http://www.oracle.com/technetwork/java/javase/compatibility-417013.html
The compiled code should be backwards compatible, so if you run it all on java7 it shouldn't matter than some was compiled using java6.
When you try the other way you get an invalid major/minor version number error.
I would assume that you can mix & match java 6 and 7 code too, just as you can (with caution) mix and match pre & post generics java.

what is the general java API compatibility rule

in detail:
if we use public API for example, write java program for example , in JDK 1.4, if should run correctly in all version above it. in all update version in 1.4, in 1.5, 1.6 and 1.7?
Also , what is the combability rule between different updater versions , for example 1.6.22 and 1.6.23 what can not be changed, what can be changed?
of course, public API definition can not be changed, how about others? javadoc? internal API definition, implementation?
It will be great if someone can point a concrete official document on this topic. thanks,
there is one example in java document bug, that they intended not to change between updater version. see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6475885
this should be one of its big picture, but we better to have a complete description on this.
need to know the complete story so that we feel safe to upgrade to bigger version.
The general rule is that any code that is written and compiled against the APIs of Java X should run on Java Y where Y >= X.
There are occasional exceptions to this; e.g. where the application's behaviour depends on some undocumented behaviour (typically a bug) in Java X that was corrected in a later version.
AFAIK, there is no single document that lists these incompatibilities. The release notes for all of the Java major releases include a list of changes that could result in breakage of older code.
Having said that, the prudent approach is make sure that you thoroughly test / retest your software when you upgrade to a more recent Java release. And if your software is shipped to customers / clients, let them know if / when it is safe for them to upgrade, and (if necessary) provide them with fixes for any problems that your testing has uncovered.
need to know the complete story so that we feel safe to upgrade to bigger version.
Feeling safe is beside the point. Thoroughly test your application on the later version. That is the only practical solution. And that would be the case even if each and every incompatibility was exhaustively documented.
Think about it. How can you know for sure that your application won't somehow be affected by change XYZ? Or that some 3rd-party library that you use won't be affected? Answer: you can't.
No manner of complaining here that you think that Oracle should handle this issue differently is going to make any difference. Not that I think that they could handle this better without changing their business model. How much would you be prepared to pay for a Java platform that guaranteed there were no version compatibility issues?
This is not a full answer but I will add that will-it-run and will-it-compile are two different things. Keywords introduced in 1.5 will prevent some 1.4 code from compiling but the byte code will run just fine.
Almost anything can be changed between versions there are no set rules for such things. Use the release notes to publish changes or review them between versions such as:
http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
Usually only bug fixes are the cause of minor versions (like you detail 1.6.22 - 1.6.23), or simple enhancements which are only ever good things. When the major version numbers change then you can expect more major changes but you still "hope" for reverse compatibility.
I don't think JDK ever changes an API that breaks backward comparability (except unintentionally).
They introduced #deprecated tag in the very beginning, probably thinking that they may need to do some API cleanup in future. But that never happens. No #deprecated API has ever been removed, or behavior changed.
if we use public API for example, write java program for example , in JDK 1.4, if should run correctly in all version above it. in all update version in 1.4, in 1.5, 1.6 and 1.7?
See this table, that shows breaking changes in public jdk APIs
See these official documents about versions compatibility:
Java SE 7 and JDK 7 Compatibility
Java SE 6 compatibility with J2SE 5.0
Incompatibilities in J2SE 5.0 (since 1.4.2)
Java SE 1.4.2 Compatibility with Previous Releases

Old projects compatible with Java 7

My old projects use Java 6 (1.6), and I don't know when I update (Java 7), they can run fine ?
There is an official list of known incompatibilities between java 6 and java 7 from Oracle (including descriptions of both binary and source-level incompatibilities in public APIs).
Also you can look at the independent analysis of API changes in the Java API Tracker project: http://abi-laboratory.pro/java/tracker/timeline/jre/
The report is generated by the japi-compliance-checker tool.
They should do, yes. Java has a reasonably strong history of backward compatibility. However, if these are in any way important projects you should still perform a thorough test pass before deploying anywhere production-like.
There shouldn't be any compatibility differences as the JVM is basically the same. However it is early days so there may be subtle differences which cause a problem which people are not yet aware of.
e.g. Eclipse looks at the Supplier in the java.exe on Windows and sets the command line arguments differently for different suppliers. It has a problem with Java 6 update 22 because Oracle wanted to change it from "Sun" to "Oracle". I believe this has been changed so it is "Oracle" in Java 7 (but still "Sun" for Java 6)
My point being, that if you write generic Java code, you shouldn't have a problem. However, if you are doing something a bit unusual, you are likely to need to re-test your application.
As was already stated backward compatibility is a very important aspect in new Java releases, so in general there should be no problems in switching to a newer Java version. In this case, however, Java 7 seems to have a few bugs in the new hotspot compiler optimizations. The Apache Software Foundation has issued a warning that their products Lucene and Solr are affected by these bugs.
http://lucene.apache.org/#28+July+2011+-+WARNING%3A+Index+corruption+and+crashes+in+Apache+Lucene+Core+%2F+Apache+Solr+with+Java+7
The affected loop optimizations can be switched off by starting java with -XX:-UseLoopPredicate.
AFAIS here, there's no Java 6 features which get deprecated in Java 7 so yes, your project should run fine.

Dropping support for JRE 1.3

We provide a popular open source Java FTP library called edtFTPj.
We would like to drop support for JRE 1.3 - this would clean up the code base and also allow us to more easily use JRE 1.4 features (without resorting to reflection etc). The JRE 1.3 is over 7 years old now!
Is anyone still using JRE 1.3 out there? Is anyone aware of any surveys that give an idea of what percentage of users are still using 1.3?
Sun allows you to buy support packages for depreciated software such as JRE 1.4. For banks and some other organizations, paying $100,000 per year for support of an outdated product is cheaper than upgrading. I would suggest only offering paid support for JRE 1.3. If anyone needs support for this, they can pay for a hefty support package. You would then shelve your current 1.3 code base, and if a customer with a support contract requires a bug fix, then you could fix the 1.3 version for them, which would likely just mean selectively applying a patch from a more recent version.
Even JDK 1.4 reached the end of its support life in Oct 2008. I think you're safe.
But don't take it from me. The people that you really need to ask are your customers. Maybe putting a survey up on your download page and soliciting feedback will help. If no one asks in three months, drop it.
Why not have your program report back what version of Java it is being run with. This will give you an idea of your user base.
I highly recommend dropping support for Java 1.3, and instead of doing a minor upgrade to Java 1.4, why not use Java 1.6? There have been massive improvements since 1.3. You really are missing out.
End-of-life is normal part of software's life cycle.
The real question you should ask/answer is whether you have a compelling business need to add features to the "old" versions. If not, you can continue to offer it for customers who need it -- but encourage everyone else to take the latest & greatest which requires 1.4 (or 1.5/1.6).
It's difficult to give figures for what companies use internally. There do exist figures for browser plugin installation, but Sun's figures are confidential.
1.3 support stopped some time ago (Solaris 8 vintage support dragged on for a bit). 1.4 has completed its End of Service Life, but is likely to be supported under Java for Business for yonks. IIRC, if you try to download 1.4 from the archives at sun.com then you are asked for some information such as an e-mail address. 1.5 is more than half way through its service life (but its still quite common on Macs).
It's not that difficult to use 1.4 features optionally. You just need to load one class via reflection (or just package it differently) and then have a 1.4 and 1.3 implementation of a light abstraction over the new features.
Why not only do critical patches for 1.3 & 1.4 if anyone actually requests them and do all new releases on 1.5 - the current oldest version supported by Sun?
I was developing with jdk 1.4 for a long time while jdk 6.0 was out. We couldn't upgrade(clients this, servers blablabah). At some point, we just upgraded without talking too much about it. Clients upgraded without being annoying, "this upgrade will fix lots of security holes, many bug fixes, improved performance :-)".
Right now, I try to keep my code compatible with jdk 1.5, I have no concern at all for people running 1.4 and below. At some point, they'll understand that it is in their best interest to "try" upgrading.

Backport Java 5/6 features to Java 1.4?

We are stuck with Java2SE v1.4 till the end of 2010. That's really nasty, but we can't help it. What options do we have to use some of the new features already now? I can think of several ways like
changing the bytecode, e.g. using Retrotranslator or Retroweaver.
backport of libraries, e.g. Concurrent Backport, but this does not help for generics.
emulation of Java 5 features, e.g. checked Collections, Varargs with helper methods, etc.
changing source code by precompilation, stripping all 1.5 stuff before final compilation, e.g. using Declawer can do this.
I am most interested in very positive experience with it in production environments using Weblogic and "real" stuff.
Thanks for your answers. Here is the summary of all relevant answers and my own research.
Changing the bytecode: The Retros
This is done by the "retro"-tools: Retrotranslator, Retroweaver and JBossRetro. Retrotranslator seems to be the most mature
and active of them tool. These tools scan all classes and change the bytecode to remove Java 5 and 6 features. Many Java5 features are supported, some
by using 3rd party backport libraries. This option is most popular and there is some positive feedback from users. Experiments showed that it's working as
expected. See a short overview on developerworks.
Pro: You can develop entirely in Java 5, build modules and all kind of JARs. In the end you just transform all classes to Java 1.4 and package your EAR.
This is easily done with Retrotranslator's Maven integration (org.codehaus.mojo:retrotranslator-maven-plugin).
Con: Conservative environments do not allow changed bytecode to be deployed. The result of the retro-step is not visible to any coder and can't be approved.
The second problem is fear: There might be some cryptic production problem and the retro-code is another step that might be blamed for that. App-server vendors
might refuse help due to changed bytecode. So nobody wants to take responsibility to use it in production. As this is rather a policital than a technical
problem, so I see no solution. It has happened to us, so I was looking for further options :-(
Compiling Java5 to Java 1.4: jsr14
There is an unsupported option, javac -source 1.5 and -target jsr14 which compiles the Java5 source to valid Java 1.4 bytecode. Most features like
varargs or extended for loop are translated by the compiler anyway. Generics and annotations are stripped. Enums are not supported and I don't know
about autoboxing, as the valueOf methods were mostly introduced in Java5.
Con: Only byte code is translated, library usage is not changed. So you have to be careful not to use Java5 specific APIs (but could use Backports).
Further you have to build all modules at the same time, because for development time you propably want Java5 code with generic and annotation information.
So you have to build the entire project from scratch for Java 1.4 production.
Changing Source back to Java 1.4: Declawer
As answered in a related question, there is Declawer, a compiler extension, that works for generics and varargs, but not for enhanced for loop or
autoboxing. The generated source "is a little funky, but not too bad".
Pro: The generated source is available and can be reviewed. In worst case fixes can be made in this source. There is no "magic", because the source
is valid Java. Some people even use JAD (Java decompiler) to get the Java 1.4 source again. The output of Jad readable is readable if you compile with debug
information and don't use inner classes.
Con: Similar to -target jsr14, you need an extra step in the deployment. Same problems with libraries, too.
Changing Source back to Java 1.4: by hand
Several answers suggested doing it by hand. For an automatic, repeating build process this is of course not useful, but for one-time changes it's
reasonable. Just automate what is possible. Maybe look at Antlr for creating a home-grown conversion tool.
Backported Libraries:
The problem is, that Java5 also ships new libraries, that are not available in older JREs, see related question. Fortunately there are several
backported libraries that give you some functionality of Java5, but can't simulate language features, like generics.
Annotations, discussed at TSS
Concurrent
com.sun.net.httpserver (Java 6 to 5)
Gif writing (Java 6 to 5)
Start your own backport project ;-)
You might copy classes you need from the JDK or other libraries, but most likely they are related to other classes.
Emulating Java5 features in Java 1.4 code:
I was thinking about some things you might do to make your life easier and still staying with Java 1.4. The most important features are typesafe collections,
here are some ideas:
Instead of using generics you can create your own typesafe containers with some template.
Add a typesafe Iterator (which is no Iterator any more).
Add asList methods that allows 1,2,...,n arguments and an array of them (to simulate varargs).
Methods for varargs (converting 1,...,n arguments to arrays) and valueOf can be put in some helper class.
sourcecode precompilation, stripping
all 1.5 stuff before final compilation
and deployment. Are there any tools
which can do this?
Yes. They're called Retrotranslator or Retroweaver. Apart from Generics (which only exist for the compiler's sake anyway), you cannot simply "strip 1.5 stuff". Enums (and maybe also some other features) have to be replaced with functionally equivalent code. Which is exactly what those tools do.
You can code with JDK 1.5 features and target JDK 1.4 at compile time. See available Javac options. However, most libraries are now using JDK 1.5 code, so you'll be stuck with old libs.
It worth noting that while Java 1.4 has been EOL for some time. Java 5.0 will be EOL Oct 8th, 2009. If anyone is promising you Java 5.0 by 2010, I would ask why?!
To simulate annotations in java 1.4 you can use http://xdoclet.sourceforge.net/xdoclet/index.html

Categories