I am currently upgrading from JAVA 1.4 to JAVA 6 SE. Some of the methods and classes have either been deprecated or there are a lot of warnings due to inefficient practices. I want to know if it is possible for me to upgrade without making any changes to my code and after the changes remote debug to fix the errors. If there's a simpler or more efficient way of doing this please share.
The usual approach is:
Run your code through the new compiler
Fix any compile errors (might happpen in some rare cases, like when you used the word enum as identifier, which is a keyword for Java 1.5 and greater)
Do a full QA cycle to verify that your application still works properly
Besides that, you should consider upgrading to Java 7 - Java 6 is also already in its end-of-life phase.
I want to know if it is possible for me to upgrade without making any changes to my code and after the changes remote debug to fix the errors.
We can't give you a definitive yes or no to that.
First, it should be noted that most of the deprecations and warnings can be ignored to start with. (Some are telling you about things that should be fixed soon, but the most egregious examples of bad / dangerous APIs were deprecated long before Java 1.4)
So one reason we can't give you a definitive answer is that we don't know what warnings you are seeing (duh!).
The other reason is that we don't know how good / extensive your test suite is. If you have a good test suite, the chances are good that any problems will be picked up. If not, or if you are relying on manual testing, then your chances of finding any problems cause by the upgrade are greatly reduced.
The other thing to note is that the documentation for each major Java release includes a section on Incompatibilities between the new release and the previous one. It is a good idea to at least skim these documents to see if any of the issues highlighted are likely to impact on your application.
Finally, most people find that upgrading doesn't result in a large swath of problems. There are exceptions of course. And if you are in the habit of depending on implementation specific behaviour rather than what the javadocs say, THAT can lead to pain.
Basically, you can run your Java 1.4 code on a Java 6 virtual machine without modifications. New API's might have been introduced, effectively deprecating old ones. Usually, the Javadoc of the deprecated API should give you a pointer what you should use instead.
Related
I have a old application written using Java 7. It runs fine in a Java 8 JRE. I do not plan on rewriting any of the code to make use of Java 8 features. Is there any technical benefit to upgrading the compiled code to the latest Java 8 JDK?
To be clear, the code is currently compiled with Java 7 and already running with the latest Java 8 JRE. It should already benefit from the Java 8 runtime improvements. This question is whether any benefits would be gained by compiling with version 8 and running with Java 8 compiled byte code.
Also, I am not concerned with non-technical benefits such as developer productivity. I think those are important but not the point of this question. I am asking for the sake of production code that has NO development team. It is purely in maintenance mode.
If I understand the question correctly, you want to know if the bytecode produced by javac will be "better" in Java 8 than in Java 7.
The answer is probably not, they constantly fix bugs in the compiler and that sometimes leads to more efficient bytecode. But you will not see any significant speedup from these fixes for Java 8 as far as I can see, the changelog only lists 2 major changes between versions.
The oracle website is terrible and I can't seem to get a list of bugfixes related to javac between versions, but here is a non exhaustive one from OpenJDK. A majority of the ones I can manage to find are fixing errors. So by updating to Java 8, there is a chance it wont compile any more due to javac more correctly following the JLS and there will be very little to no "improvements" to the bytecode.
The main benefit is that Java 8 has the latest bug fixes where as Java 7 isn't being publicly updated.
Also if you are going to run code on an Java 8 JVM, you may as well have just one version of Java installed.
Java 8 might be faster, and it has better support for new features like G1. However, it might be slower for your use case so the only way to know is to test it.
Is there any technical benefit to upgrading the compiled code to the latest Java 8 JDK?
If you are asking whether there is any benefit in re-compiling Java 7 code in a Java 8 compiler, the answer is; almost nothing.
The only subtle difference is that there have been minor differences to the Java API, so there might be very subtle differences the Java 8 compiler might find that the Java 7
Other minor differences are the magic number at the start of the file, possibly the order of the constant pool. The byte code is basically the same, even the support for invokedynamic which was added for lambdas existed in Java 7 but just wasn't used that way.
It could help by creating awareness.
When you switch to Java8, you might find additional warnings being emitted by javac. Example: type inference has been greatly improved with Java8. And that could eliminate the need for #SuppressWarnings annotations in your current code base (and when such annotations are no longer required, the compiler warns about that).
So, even when you don't intend to modify your code base today, switching to Java8 could tell you about such things. Increasing your knowledge can help in making informed decisions.
On the other hand:
I saw some questions here about (rare) situations where Java8 refused to compile Java7 code. So, switching to Java8 also carries a (minimal) risk of running into that kind of problem.
And: even when you don't intend to touch your code base today, there is a certain chance that you change your mind later on. And then, when not paying attention, you might exploit Java8 features. Which could complicate "field updates"; as you now have two versions of your source code to maintain!
Then: in case you have customers running the product using a java7 jre; you have to be really careful about the binary fixes you give to them. We have such a setup; and I have wasted time more than once because I accidentally put a single Java8-compiled class onto a Java7-driven test system. That simply can't happen when your dev and test/customer setup is all Java7.
Long story short: there are a few subtle advantages, and certain risks (where the significance of the risks mainly depend on your overall setup).
I would do for at least these facts.
1) HashMap internals (it is faster under jdk-8)
2) Lots of bugs fixed that might be transparent for you (runtime optimizations) that will make your code faster and better without you actually doing anything.
3) G1 Garbage Collector
EDIT
From a technical point of view this sounds more like something to do with Ahead of Time Compilation or something that a compiler might improve by analyzing the code more. As far as I know such things are not done in java 8 compiler.
From a developer point of view - there are plenty. Increased productivity is the most important one for me.
EDIT 2
I know only two points that matches your second query:
–parameters
to preserve the method parameter names.
-profile
Called Compact Profile Option for a smaller footprint.
If you have no other reasons to recompile your application, then it probably does not make much difference, as stated in the accepted answer.
However, if you have to recompile it even only once, consider this:
Your application source code is compatible with Java 7, and most likely 8 too;
In the eventuality that the code does not compile with Java 8, it will probably not compile either with a Java 8 compiler in Java 7 source compatibility mode (-source 7 with javac);
Your developers and CI will need to run unit and integration tests against a Java 8 runtime to be as close as possible to the production environment. Developers will also need to run the application on the same Java 8 runtime when running it locally;
It is more difficult to compile with a JDK 7 and run with a JRE 8 (in the same build process, or in the same IDE) than doing everything with the same version;
There is no benefit of using -source 7 instead of -source 8 if you compile with a JDK 8 and your target runtime is Java 8;
Using -source 8 guarantees that the developer is using Java 8 (or later) for both compilation and runtime (as it enforces -target 8).
In conclusion, don't recompile it if you don't need to. However, on the first occasion you have to recompile (due to code changes), switch to Java 8. Don't take the risk of having a bug due to environment mismatches, and don't restrict the developers without a good reason.
I am a hobbyist java programmer using NetBeans IDE. A problem I face with programming in Java is choosing the correct target JRE version. I understand that most of my friends have at least java 6, but few have a totally up-to-date version with which I compile. I know how to compile for a particular target run-time environment on NetBeans; the problem is that by using an earlier target release of Java, the compiler expects code written in that version.
For a specific example, I occasionally use a Java 8 lambda instead of a new Runnable(){}, however the compiler (or at least NetBeans) doesn't accept this 'modern' code. Another example is the use of the diamond operator, or the use of multiple-exception catch statement, neither of which are supported by Java 6. The language evolves and the compiler evolves, but older versions of Java cannot handle the change. To distribute my code, I am forced to use what some might consider outdated code.
My question is: Is it considered good practice or common practice to write Java for an outdated target version to provide compatibility? Is there some form of 'translator' or cross-compiler for Java code?
My question is: Is it considered good practice or common practice to write Java for an outdated target version to provide compatibility?
It is common practice.
Whether it is "good practice" or not, is highly context dependent. There is a pragmatic trade-off between supporting older applications whose developers don't want (or can't) upgrade, and holding back the development of your application by not making use of new (and presumably beneficial) features.
There is no universal "best" answer.
Is there some form of 'translator' or cross-compiler for Java code?
Effectively, no. For old versions of Java there were "retro-weavers" which allowed you to run "newer" Java on "older" platforms. However, this approach seems to have died out by Java 6.
To answer your first question, it really depends on the standards set by the company/office that you are working for.
From my experience, most of time big companies tries to stay with matured and well established development platforms, they might not give the cutting edge features of the new language, but the companies want the base platforms to be stable and secure first. And if the codebase is large and the project has been in development for a long time, they normally don't bother jumping into the new platform, since that means they might have to invest more resources to rewriting/refactoring a lot of code, which is not always economically lucrative.
I love using those features that you mentioned in my personal projects, but in my office works we are still using JDK6.
As for the second question, I think there are no workable things at this moment that can do the "translation" that you mentioned.
From my experience this isn't a big problem in the industry. Java is used mostly on the server, not so much on the desktop. And to setup a server with the required Java version is not a big deal. For desktop applications I also seen the approach to ship the JRE with the application. It is a little bit ugly to ship a small application (let's say 5 MB) with a 60 MB JRE, but in the "enterprise environment" it doesn't matter and is a practical way to provide the correct JRE. However, I don't like this approach since it leaves open questions, like how to ship security updates to the JRE.
And by the way: Is Java 6 still supported? To use an old JRE is pretty big security issue.
We're migrating from Java 6u17 to Java 7u45.
The application is run under Weblogic 12.1.1.0, it has tons of legacy code and dependencies (versions of which we left unchanged).
After recompilation we got the app running.
At first it seemed all fine but in a while we ran into 'gc overhead limit exceeded'. It emerged from one of the batch jobs that worked perfectly fine for years under Java 6_17 (and it hasn't been changed since).
Obviously there is more to just 'recompile and run', at least one has to consider GC tweaking.
So the question stands, has anyone experienced problems (or maybe surprises) during the migration of an enterprise app from Java 6 to Java 7?
Or are there any guidelines/good practices?
PS: This is purely practical question. Let's omit discussion of pros and cons, language changes and so on.
I just yesterday upgraded my code from 6.17SE to 7.51SE (that is, recompiled it). Is it an enterprise app? No. It's a library of about 500 classes, that almost entirely uses java.lang, util, and io, with a smattering of java.lang.reflect and a pinch of java.net.
The not-so-hardest part was re-pointing javac, the CLASSPATH and PATH to the correct JDK. You'll find compilation errors be more verbose, which is, at first impression, a slight improvement. (I can't comment on garbage collection tweaking.)
Not a single change was necessary in any of my code, which is not surprising. From the "migration" link, as provided by #Andremoniy:
Almost all existing programs should run on Java SE 7 without modification. However, there are some minor potential incompatibilities in the JRE and JDK that involve rare circumstances and "corner cases" that are documented here for completeness:
http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#incompatibilities.
As far as language improvements (which I know you don't need advice on, but I'm going to mention because it's so related), I'm likely to first take advantage of diamond generics inference, catching multiple exceptions and auto-closeable try blocks.
Good luck.
Java 7 has been around for a while now. Now if an application is to be migrated to Java 7 without any changes (code/configuration), are there any inherent advantages or drawbacks? I was curious to know what the problems are faced during such migration.
EDIT:
By Migration I mean the code will remain the same but the runtime will change to Java 7 As I mentioned no code/configuration changes, so thing which I think should impact the application is new compiler/VM level default optimizations. So I was looking for anything which would impact the overall application behavior.
The obvious disadvantage at the moment that I'm finding with my app (which was written in Java 7 to start with) is that most people don't have 7, and it takes a bit of effort to get it. The default Java download page at the time of writing still points to Java 6, not 7, and most of the current Linux distributions just seem to have 6 installed by default as well. Ubuntu 11.10 is the first to even have Java in its repository.
Also on the Ubuntu side of things, one thing I've noted is that even if Java 7 is installed, I haven't found a clean way to check if it's the default yet (and again, chances are it's not.) I'm just using a shell script that parses the output from update-alternatives --query java and launches it appropriately.
It was a conscious decision on my part to go with 7 because there were a number of new features in it that I could take advantage of, and by the time said app actually hits the point where I'd consider it out of alpha / beta I hope Java 7 will have gained more of a foothold then anyway!
The advantages pretty much all centre around using the added features - I've found the try with resources construct has made a lot of my code using IO stuff easier to read (no more nested try / finally's inside try / catches) and I'm using some of the extra APIs like the filewatcher API too. I also rather like the fact JComboBox and the underlying models are now generic which saves a fair bit of casting in Swing apps.
In short though, if you're not actually going to take advantage of any of the Java 7 features and you're just upgrading for the heck of it, there's little motivation to do so until Java 7 at least becomes a bit more established. It's made my code somewhat cleaner and been helpful with some of the additional libraries, but it's also caused a fair few headaches as well.
I would also consider the probability/requirement change of running your new code(java 7) in java 6 or less since some features will not compile like the following:
Strings in switch statements
try-with-resources statements
improved type inference for generic instance creation ("diamond operator")
improved exception handling (multi-catch)
Make sure the version of java used on your considered projects is not likely to be enforced before switching.
The question is really "when", not "if". If you have a pressing need for some of the new Java 7 features (doubtful) then it's obvious.
Otherwise I'd personally wait about year or so to weed out any other possible showstoppers & headaches, before seriously considering a migration production and UAT environments.
Still, you should already have an environment with Java 7 running just to get an idea of what you'll be in for. Java 6 will be retired at some point and you should be well prepared to make the transition.
I think mostly you will be fine with the migration, although you should check with link provided by Oracle about the incompatibilities between Java 1.6 and Java 7
http://www.oracle.com/technetwork/java/javase/compatibility-417013.html
There are few source level incompatibilities like "Improved Exception Handling" in Java 7 which could cause some problems
It is good question and my answer is totally based on experience and new features provided by java 7.
All new features ease the work for developer rather than creating cross compatibility issues.
Only drawback i see in cross compatibilities among different thirds party jars.
You can experience some performance issue between two java versions. And it will depend on area of java code, for details please have a look http://inebium.com/post/java-7-new-release-performance-code
I work on a project that uses multiple open source Java libraries. When upgrades to those libraries come out, we tend to follow a conservative strategy:
if it ain't broke, don't fix it
if it doesn't have new features we want, ignore it
We follow this strategy because we usually don't have time to put in the new library and thoroughly test the overall application. (Like many software development teams we're always behind schedule on features we promised months ago.)
But, I sometimes wonder if this strategy is wise given that some performance improvements and a large number of bug fixes usually come with library upgrades. (i.e. "Who knows, maybe things will work better in a way we don't foresee...")
What criteria do you use when you make these types of decisions in your project?
Important: Avoid Technical Debt.
"If it ain't broke, don't upgrade" is a crazy policy that leads to software so broken that no one can fix it.
Rash, untested changes are a bad idea, but not as bad as accumulating technical debt because it appears cheaper in the short run.
Get a "nightly build" process going so you can continuously test all changes -- yours as well as the packages on which you depend.
Until you have a continuous integration process, you can do quarterly major releases that include infrastructure upgrades.
Avoid Technical Debt.
I've learned enough lessons to do the following:
Check the library's change list. What did they fix? Do I care? If there isn't a change list, then the library isn't used in my project.
What are people posting about on the Library's forum? Are there a rash of posts starting shortly after release pointing out obvious problems?
Along the same vein as number 2, don't upgrade immediately. EVERYONE has a bad release. I don't intend to be the first to get bit with that little bug. (anymore that is). This doesn't mean wait 6 months either. Within the first month of release you should know the downsides.
When I decide to go ahead with an upgrade; test, test test. Here automated testing is extremely important.
EDIT: I wanted to add one more item which is at least as important, and maybe more so than the others.
What breaking changes were introduced in this release? In other words, is the library going off in a different direction? If the library is deprecating or replacing functionality you will want to stay on top of that.
One approach is to bring the open source libraries that you use under your own source code control. Then periodically merge the upstream changes into your next release branch, or sooner if they are security fixes, and run your automated tests.
In other words, use the same criteria to decide whether to use upstream changes as you do for release cycles on code you write in house. Consider the open source developers to be part of your virtual development team. This is really the case anyway, it's just a matter of whether you choose to recognise it as part of your development practices.
While you don't want to upgrade just because there's a new version, there's another consideration, which is availability of the old version. I've run into that problem trying to build open source projects.
I usually assume that ignoring a new version of a library (coz' it doesn't have any interesting features or improvements) is a mistake, because one day you'll find out that this version is necessary for the migration to the next version which you might want to upgrade to.
So my advice is to review carefully what has changed in the new version, and consider whether the changes requires a lot of testing, or little.
If a lot of testing are required, it is best to upgrade to the newer library at the next release (major version) of your software (like when moving from v8.0 to v8.5). When this happens, I guess there are other major modifications as well, so a lot of testing is done.
I prefer not to let the versions lag too far behind on dependant libraries.
Up to a year is ok for most libraries unless security or performance issues are known.
Libraries with known security issues are a must for refreshing.
I periodically download the latest version of each library and run my apps unit tests using them.
If they pass, I use them in our development and integration environments for a while and push to QA when I'm satisfied they don't suck.
The above procedure assumes the API hasn't changed significantly. All bets are off if I need to refactor existing code just to use a newer library version. (e.g. Axis 1x vs. 2x) Then I would need to get management involved to make the decision to allocate resources. Such a change would typically be differed until a major revision of the legacy code is planned.
Some important questions:
How widely used is the library? (If it's widely used, bugs will be found and eliminated more quickly)
How actively developed is it?
Is the documentation very clear?
Have there been major changes, minor ones, or just internal changes?
Does the upgrade break backwards compatibility? (Will you have to change any of your code?)
Unless the upgrade looks bad according to the above criteria, it's better to go with it, and if you have any problems, revert to the old version.