In IE, I can use the classid "clsid:CAFEEFAC-0015-0000-0011-ABCDEFFEDCBA" to tell it to use java version 1.5.0_11. Is there an equivalent for Firefox and other browsers?
I can use the classid "clsid:CAFEEFAC-0015-0000-0011-ABCDEFFEDCBA" to tell it to use java version 1.5.0_11
Not any more, you can't, for good (security) reasons. See http://java.sun.com/javase/6/webnotes/deploy/deployment-policy.html
There is an IE-only clsid mechanism for asking for "5.0_(something)" in general - http://java.sun.com/javase/6/webnotes/family-clsid.html . This was introduced in 5.0u7 so if you have any one JRE from u7 onwards installed you get this behaviour, otherwise you get the old and incompatible behaviour.
Sun did not deign to provide a similar mechanism for other browsers until 6.0u10, when they added a bunch more mechanisms for choosing versions and deprecated all the old ones including the 5.0u7 family chooser. See https://jdk6.dev.java.net/plugin2/version-selection/ for all the gory details.
So what behaviour you get depends not only on the browser and whether the version of the JVM you want is installed, but what other versions are installed as well. The new behaviour is at least consistent, but it is completely different to all that went before and not entirely compatible. By the time your apps' deployment HTML has been updated to cope with it, they'll probably work with 1.6 anyway.
So in summary, as usual with applets, the whole thing's a bloody mess. Yay.
Related
recently I was researching for common vulnerabilities for a particular version of JRE (1.8.0_151) we still have in use and stumbled over cvedetails.com. The result was pretty confusing, since there seems to be no known CVE for this particular version at all. At least, the page does not list this version. However, the page lists results for all kind of newer JRE versions. This could lead to the (probably false) assumption that version 8.0_151 is more secure as the following newer JRE releases and that there wouldn't be the need to update.
List of all CVEs for JRE on cvedetails.com
Does someone know why the particular version isn't listed or if it perhaps counts together with version 152?
Additionally, what would be your recommended update strategy approaches for JRE respective security. Is there any best practices? I am aware that it is a matter of time and money to invest in regards of testing compatibility with the application to use with, but apart from this, it would be great to be aware of the best reasons to stay up to date with JRE.
Many thanks!
You should assume that the vulnerability exists not just in the specified update, but also in all prior updates of the given JRE version. So if the alert calls out 1.8.0_151, you should assume that the issue exists in 1.8.0_anything-equal-to-or-less-than-151.
This isn't just because it's better to err on the side of caution. It's because that's almost always the actual reality of the situation.
There are a couple of reasons why that CVEDetails summary page is incomplete in the sense of not listing every affected update. The first is that Oracle changed the format of its CVE notices back in 2014. The earlier format was something like this:
Unspecified vulnerability in Oracle Java SE 7u40 and earlier, Java SE 6u60 and earlier, and Java SE Embedded 7u40 and earlier ...
which makes it clear that the vulnerability does not exist only in 1.7.0_40, 1.6.0_60 and Embedded 1.7.0_40. The fact the the vulnerability exists in earlier updates is true for practically every vulnerability, not just in Java but in any software. The only time that's not the case is when a vulnerability was introduced in an update, and thankfully that's pretty rare.
Oracle's newer format is something like this:
Unspecified vulnerability in Oracle Java SE 7u45 and Java SE Embedded 7u45, and OpenJDK 7 ...
which no longer makes any statement about the existence of the issue in earlier updates. Oracle would probably say that they do this because the earlier updates are no longer supported and therefore there's no point in even investigating whether they're vulnerable or not.
In fact Oracle's current format makes that position explicit:
Vulnerability in the Java SE, Java SE Embedded product of Oracle Java SE (component: Networking). Supported versions that are affected are Java SE: 7u241 and 8u231; Java SE Embedded: 8u231.
Only the currently-supported versions are specified as being affected. But the odds are overwhelming that the issue exists in earlier updates too.
The second issue is that even when the original alert format specified "update NNN and earlier", that "and earlier" part is not reflected in the CVEDetails summaries. For example, the CVEDetails summary for JRE 1.7.0 shows no vulnerabilities for 1.7.0_39, 1.7.0_38, 1.7.0_37, ... even though those were all affected by the "7u40 and earlier" issue in the example of the original alert format I showed above.
Additionally, what would be your recommended update strategy
approaches for JRE respective security. Is there any best practices?
Opinions vary, and opinions are off-topic for StackOverflow. But IMO, whenever a new update comes out (even if it has no security fixes) you should revalidate your app against the new JRE, so you know in advance whether there's going to be trouble when your customers apply that JRE update. If there are incompatibilities then you should resolve those ASAP.
If the vulnerability is severe and is exploitable in your app then you should let your customers know that they should apply the JRE update, perhaps after they've first installed a new update of your app if you found incompatibilities when you revalidated. If the vulnerability is mild and/or not exploitable in your app then you should let your customers know that, let them know if the JRE update requires an app update, and let them decide whether to move to the updated JRE.
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.
Updated
Take http://bugs.sun.com/view_bug.do?bug_id=6857057. We witnessed this in JRE 6u17. How do I know which version of the JRE contains the fix? The general consensus on the Internet seems to be 6u18 - but how can I tell this from the bug database? It says fixed in 6u16-rev, but I don't know what '-rev' means. Also it says it still affects version 6u18 - so is there some time dilation going on?
Note
Originally I assumed I'd need to build against a newer version of the JDK, so asked how I'd know which version of the JDK contained the fix. I've updated the question based on mindas explaining its actually the JRE which contains the fix.
You need to understand the difference between static and dynamic linking. In Java world, all JVMs are obliged to load classes as they are referenced. In other words, your code which was compiled against older JDK version does not have the information about how older JDK implemented a particular method.
Unless the method signature has changed (from your bugs.sun.com link I assume it hasn't), you should not need to rebuild your classes. Even if it had, you would be getting a different error (something like NoSuchMethodException).
Java came up with "write once run everywhere".
How to do the trick with all the frameworks in the long term?
I wrote an application with JSF and richfaces a few years ago. Browsers have evolved and introduced new features and of course new bugs. Now the application still runs, and sometimes it shows javascript errors from the underlying libraries.
Do we really have to reimplement a finsihed application (no use cases to add) due to technical 'improvements' ?
EDIT: The application I mentioned was just an example. Same things easily happen if vendors change licenses. (Oracle could charge for a vm and open vm is not compatible with you application stack etc.)
Even if we believe "write once, run anywhere", it's not quite the same thing as eternal backward compatibility. Pragmatically, you must expect future versions of frameworks to change some things. Sometimes this will be the removal of what used to be guaranteed behavior (the worst kind of change), other times bugs in your code will go unnoticed until some future version of the library reveals that you were relying on an implementation detail that wasn't guaranteed. More rarely, your old code will reveal a novel bug in the latest version.
In an ideal world, we'd write code which relies only on guaranteed behavior, and guarantees would never be removed, and hence valid code would continue to work forever. Against that, it's hard to prove that your program is totally correct, and the language/framework/library developers make decisions about whether they can add the improvements they want to, while retaining perfect compatibility.
For compatibility to win the argument, the original API has to be strong enough and stable enough to survive without disruptive changes. If it isn't, then either non-compatible changes will be made, or else the API will be abandoned entirely. Either way, your program won't run any more unless you have an old version tucked away somewhere to run it on.
You ask how to do the trick - it requires either really good and somewhat lucky interface design in the first place to allow all the extensions you come up with later, or else a firm commitment and a "business case" (or non-business motive) to support the "old" version indefinitely. For example, Python 3 isn't compatible with Python 2, but Python 2 is still actively supported with updates, so old Python code still runs. C99 removes only a few features of C89, and if all else fails C89 compilers are still actively maintained. Browsers support a thousand and one old versions and non-standard quirks of HTML. I don't know how JSF and richfaces compare to those, or how much they output pages that rely on support for "old" (or quirky) HTML/CSS/Javascript behavior from the client.
So it can happen, at least for a while. But there are IE6 features which are no longer available in any browser that's safe to let out on the web (I guess you could run IE6 in a sandboxed VM, or on a machine you don't care about), so it's a question of what you depended on in the first place. Could it have been predicted that proprietary browser extensions would be dropped like a stone in future versions? Probably, but could those IE6 app-writers have achieved what they wanted to using proper standards available at the time? Not always. Even for those who didn't get involved with IE6, if your app falls into a similar trap, you're out of luck.
I don't suppose anyone can seriously promise "run anywhere, forever". Sooner or later Linux and Windows and MacOS will all be obsolete, new OSes will come out, and no one will bother to write JVMs for them, so none of your Java apps will run any more. (I have an old MS DOS game that I thought was way cool but it won't run under a Windows DOS box. THe company came out with a Windows version but they seriously redesigned the game and, in my humble opinion, destroyed everything that made it fun. Bummer man.)
In the meantime, upward compatibility of new versions is a great thing, but every now and then vendors decide that it's just too much trouble.
It seems that you are speaking not about application but about applet (because you mentioned java script). Moreover this is an applet that calls javascript from page where it is deployed. In this case it is not exactly pure java. It sounds like to call platform dependent command line using Runtime.exec(), then change OS and complain that application does not work.
Or probably I did not understand correctly you use-case?
Programming languages and technologies evolve. Speaking broadly, if a web app is pretty basic, it may be able to take updates without requiring many changes.
Java-based languages seem to update less frequently than languages in the Microsoft stack. JSF 2 has some big changes over previous versions, however, and Richfaces 3.x apps will require migration if you want to use Richfaces 4.x.
As a workaround, you don't always have to upgrade; there are plenty of sites written in older languages (classic ASP for one), deployed and still running happily.
I am using the AWTUtilities class in my application to create custom window shapes. As far as I know, there is no other way to do it. It is a requirement.
The javadoc generation gives me this error:
warning: com.sun.awt.AWTUtilities is Sun proprietary API and may be removed in a future release
What exactly does this mean? I can use it, but it may stop working with any release? Why put it in, then? More importantly, and the real question here, if Sun takes it out, will they likely replace it with another way to do the same thing? Is that what the warning is for?
I suppose I could just check for the presence of the AWTUtilities class before calling the code. But that's just obnoxious if I don't need to do it.
Does anyone have any experience with similar classes? Were they eventually accepted into the API and the warning removed or replaced with another method of doing the same thing? Do I need to be concerned about this?
FYI, I have read this:
How to distribute AWTUtilities
The Oracle documentation states:
Note: the com.sun.awt.AWTUtilities class is not part of an officially supported API and appears as an implementation detail. The API is only meant for limited use outside of the core platform. It may change drastically between update releases, and it may even be removed or be moved in some other packages or classes. The class should be used via Java Reflection. Supported and public API will appear in the next major JDK release.
JDK 7 has been a long time coming so it could be awhile. Whether you should use it is a risk management question that only your company can answer. If we are talking about an internal application where the deployed JRE can be guaranteed then you are not going to have a problem because you can guarantee a compatible JRE. If we are talking about deploying to external customers then you need to have a support plan if this provisional API ever changes.
A stable way to do this would be to create a Shell in SWT as per this snippet and then use the SWT_AWT bridge to get a Frame to use in your application:
java.awt.Frame frame = SWT_AWT.new_Frame(shell);
If you are just deploying to a single platform (like Windows) then tossing a single SWT jar plus the native library. If you are targeting multiple platforms then this becomes a pain.
So those are the two choice: deal with the AWTUtilities risk or use the SWT_AWT bridge.
EDIT:
Some time has passed and Java 7 is out. There is documentation on the officially supported way to accomplish this in the Java Tutorials. The section "How to Implement a Shaped Window" at the bottom gives an example. This of course assumes you can mandate Java 7
You don't need a new Frame object, you can only use
this.setShape(shape);
or your frame name like this
Frame1.setShape(shape);
a lot of AWT methods has been applied to java.awt.Frame