Community
Participate
Working Groups
3.1 Compiling with compiler complaince 1.4 against a 5.0 VM can cause some trouble with covariant return types. Therefore when detecting the default VM for a fresh workspace the launching plug-in should switch the default compiler compliance to 5.0 when a 1.5 VM is detected.
Marking as a 3.1.1 candidate.
See Bug 102560 for a specific example.
The launching plugin is started too late to do this. For example, Launch a target with a clean workspace, switch to the java perspective, open new project wizard. The new project wizard shows the default compliance level, but the launching plugin will not get started until you give the plugin a name and click next in the wizard. JUI can test the java version by calling JavaRuntime.getDefaultVMInstall(), casting the returned IVMInstall to an IVMInstall2 (with appropriate checks) and calling getJavaVersion(). Moving to JUI
Doing this change for 3.1.1 seems somehow risky for me. Product providers might not expect the default compliance level be 5.0 when running on a JDK 5.0, especially since this wasn't the case in 3.1. Tagging for 3.2.
Kevin, I looked into ways to figure out when JDT is activated the first time one a new workspace put this isn't easily doable (had a discussion with John and Thomas about it). Another idea that came to my mind is that we trigger the default JDK initialization when the dialog gets opened, not when the project gets created. This will cause unnecessary plug-in activation in the case the user will cancel the dialog but this shouldn't happen to often. Is there any API for use to trigger this ? Will JavaRuntime.getDefaultVMInstall() do this as a side effect.
Created attachment 26497 [details] Patch for setting default compiler compliance based on running VM Attached is a proposed patch to org.eclipse.jdt.internal.compiler.impl.CompilerOptions. It switches the default compliance level based on the running VM. I've tested it and it seems to work correctly: on a 1.5 VM, options are all set to the 5.0 level, and on previous VMs the original defaults still hold.
Jess, I think the patch will not work in cases where clients first start Eclipse with a 1.4 VM and then with a 1.5 VM. The default VM detection only takes place once put our detection is done on every startup. Resulting in situations where the compliance level will be 5.0 but the default VM will be 1.4.
Dirk, Re: comment #5 - anything that starts the launching plugin will trigger the vm initialization process, calling getDefaultVMInstall should do the trick.
Kevin, thanks for the info. Can you add the code to set the default compiler compliance level to 5.0 when you auto detect the VM the first time and the VM is 5.0. I will then add the call to getDefaultVMInstall to the new project wizard to make sure it is initialized before we present the first page.
Moving to JDT/Debug. Please move back to JDT/UI after you added the changes so that we can add the initialize call.
Fixed in JavaRuntime.detectDefaultVM() To test on Windows, launch an empty workspace, open the Launch dialog and create a new Java application launch config (ensures default VM is detected). Close the dialog and then create a new Java project to see the default settings at 5.0. Needs to be tested on MacOS.
MacOSXVMInstall behaves differently. Its detectInstallLocation() method returns the JDK located in apple's "CurrentJDK" instead of the JDK that Eclipse is running on. This means that even if you are running Eclipse on 1.5, the detected default JDK is 1.4.2 (on my machine at least). Andre is this intentional?
IIRC, on Windows there is no concept of a "default" Java installation defined by the OS. So Eclipse tries to "guess" this by looking at the JVM Eclipse itself uses. I'd consider this a workaround. On MacOS X there is the concept of a default Java installation (defined by Apple). Eclipse uses that instead of looking at its own Java version (which I consider an implementation detail defined by us).
Thanks Andre. moving back to JDT/UI (see comment 10)
One question: are we only talking about a one time switch ? Or rather some prompting whenever we detect a mismatch in between JRE level and project setting ? Note that the latter should likely be implemented in term of classpath markers (JDT/Core).
My idea was more a one time check. When we detect the default VM on a fresh workspace then we switch compiler compliance to 5.0 iff VM >= 5.0
I added a call to JavaRuntime.getDefaultVM to the constructor of JavaProjectWizardFirstPage. Martin, please speak up if you think this wasn't the right place. In addition to the source, class file and compiler compliance we have also set the enum and assert identifier to error. So JDT/Debug should add the following lines defaultOptions.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR); defaultOptions.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR); In addition JDt/Debug should check if the VM version is >= 1.5. We should switch to 5.0 compliance for J2SE 6 and 7 as well. Moving to JDt/Debug to consider the changes. I will release the call to initialize the VM.
These are irrelevant: defaultOptions.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR); defaultOptions.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR); If source > 1.5, then these are keywords, so cannot occur any longer as identifier. These optional diagnostics are defined to anticipate migrating to upper source level.
Regarding comment #18: Agree, however the UI checks these to fake the Default compiler compliance level check box. We compute the check box from the 5 "compliance level" values. So if it doesn't cause harm I would like to see defaultOptions.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR); defaultOptions.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR); added.
Marking as 3.1.1 candidate
CC'ing Steve. Do you know if this will cause any problems for upstream tools that potentially generate source code, and may be reling on default compiler compliance settings to be at the 1.4 level? Note, the default setting will be 1.4 unless the Eclipse runtime is started on a 1.5 VM. We want to ensure this is an agreeable fix to add to 3.1.1.
Not only in 3.1.1 but even in the 3.2 timeframe there will be others (most notably EMF) generating Java code at a 1.4 compliance level (not sure how much they will "rely" on the compliance setting). In the 3.2 timeframe this will often be done while running eclipse on a 1.5 VM. I don't think it would be appropriate to put this sort of change in a maintenance release like 3.1.1 as there are too many scenarios out there that could be affected. As for 3.2, keep in mind that this could in some cases be seen as a breaking change (a change of default api/language level that could break some scenarios) but at least for 3.2 we have much more runway to detect and fix these cases. Adding Ed Merks for comment about how much EMF "relies" on the 1.4 compiler compliance setting. In EMF 2.2 (aligned with platform 3.2) will EMF generated code always work with the JDT compiler compliance settings set to either 1.4 or 1.5? You may want to look at bug 102560 for an example of how 1.4 compliant code may not compile against a 1.5 set of libraries. As for products, there will certainly be the need to have projects that rely on 1.4 compliance for a long time. This will include products that run on a 1.5 VM but target 1.4 VMs (some will be targeting both levels). Could there be an ini file setting (config.ini or other) that could restore the original behavior or explicitly set what the setting should be for fresh workspaces? Or perhaps the original behavior should be the default and the setting should be to turn on having the compiler compliance level "track" the VM level that eclipse is running on. Perhaps then, the Eclipse SDK could ship a config.ini (or other) that has this flag on.
I'm not sure if the proposal is simply to change the compiler compliance level to 5.0 but leave the actual "default compliance settings" at 1.2 and 1.3 as they are now or to change those too? It does seem risky to change this in a point release. Steve's approach of making the behavior change optional seems like a wise idea. I believe all EMF generated code will compile fine with 5.0, although with enough warning messages to drive the poor user around the bend, but we did have a case where the source code of EMF itself would not compile with 5.0 https://bugs.eclipse.org/bugs/show_bug.cgi?id=105538
Based on the comments from Steve and Ed I think we should not add this to 3.1.1, and perhaps further refine how this works in 3.2. Removing 3.1.1 target milestone.
I agree; the situation is scary enough already. Ed: relying on default workspace compliance is very risky. Compiling in 1.4 compliant mode against 1.5 JRE is going to cause problems (mostly due to covariance and new type kinds: enum...). I think you want to ensure that if you rely on 1.4 compliance, then you feed a 1.4 JRE on the buildpath. If this was occurring, then our change wouldn't be so risky as anybody would want a consistent JRE and compliance setting.
In 3.2 timeframe, we will likely change the compiler defaults to reflect 1.5 settings. We once did that already when switching Eclipse codebase from 1.3 to 1.4. This change may thus not be mandated for 3.2; unless it is able to calibrate the workspace default settings based on the default JRE (including all the way back to 1.3 runtimes).
Thinking more of it, I think we should revisit this fix. Having the worksplace compliance match the default JRE is good, but this should occur at the time one changes the default JRE (which is induced on startup sometimes, but not solely since can be manually performed by user). When default JRE is changed, then user should be prompted to align compliance setting accordingly (and I believe the reciprocal is true too). Note also that the consistency check should work backward as well. Let say that a default JRE is set to 1.4, when our default setting is 1.5, it should switch back our compliance level to 1.4. Once we have 1.5 compliance level by default, having a 1.4 JRE on the classpath is not a big issue (compared to 1.4 compliance against 1.5 libs); and would simply mean user cannot exploit 1.5 libs (generics etc...) but still develop standalone 1.5 code.
So basically, this fix (as it is) would have been useful only in 3.1 maintenance branch so as to bridge the gap in between 1.5 JRE and 1.4 default compliance. But due to client assumptions, this change cannot be introduced without breaking these.
in 3.2, launching will only update the default compliance settings if the settings are actually default settings of the wrong compliance (so as not to overwrite some user or other tool settings).
Fixed - added additional compliance settings as: defaultOptions.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR); defaultOptions.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
Please verify, Kevin.
Verified
I still get Eclipse defaulting to 1.4 complicance level on a new workspace, with a >= 1.5 JDK. My eclipse build: Version: 3.2.1 Build id: M20060921-0945 Java version: 1.6.0-b105
Unfortunately, 3.2.x only checks for 1.5 (not >= 1.5). Fixed in 3.3 - see bug 165223.