Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The java builder should use the correct compiler compliance to build the project #1290

Open
testforstephen opened this issue Feb 20, 2020 · 10 comments
Assignees
Labels

Comments

@testforstephen
Copy link
Collaborator

Environment
  • Operating System: MacOS and Windows 10
  • JDK version: any
  • Visual Studio Code version: 1.41.x or 1.42.0-insider
  • Java extension version: 0.57.0
Steps To Reproduce
  1. Have java.home to point to JDK 13, and launch the language server.
  2. Have Java 8 installed in the machine.
  3. Configure multiple JDKs in the user setting.
    "java.configuration.runtimes": [
        {
            "name": "JavaSE-13",
            "path": "C:\\Program Files\\Java\\jdk-13.0.1"
        },
        {
            "name": "JavaSE-1.8",
            "path": "C:\\Program Files\\AdoptOpenJDK\\jdk-8.0.242.08-hotspot"
        }
    ]
  1. Open an eclipse Java 8 project 26.environmentVariables.zip
    .
    image

Current Result:

See the screenshot above, the PROBLEMS viewlet reports a warning on the project: "The compiler compliance specified is 13 but a JRE 1.8 is used". This means the classfile built by the ls is targeting to java 13, that would make it not able to be launched in JDK 8.

Besides, the debugger has fixed a bug microsoft/vscode-java-debug#753 about using the project's Java runtime to launch the application. The latest debugger would fail at this case.

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: EnvrionmentVariable has been compiled by a more recent version of the Java Runtime (class file version 57.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:757)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

Expected

The language server should generate the compatible .class files with the project's Java Runtime.

// @fbricon @snjeza

@snjeza
Copy link
Contributor

snjeza commented Feb 20, 2020

@testforstephen

Have java.home to point to JDK 13, and launch the language server.

That causes Java LS to use the workspace Compiler Compliance level 13.
Your project inherits it and reports the warning.
You should configure your project by adding 26.environmentVariables/.settings/org.eclipse.jdt.core.prefs with following contents:

eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

or use the following settings:

 {
      "name": "JavaSE-1.8",
      "path": "C:\\Program Files\\AdoptOpenJDK\\jdk-8.0.242.08-hotspot",
      "default": true
}

@testforstephen
Copy link
Collaborator Author

@snjeza Most of users don't have knowledge about the .settings. If project compiler compliance setting is undefined, how about auto assign a compiler compliance compatible with the project JRE_CONTAINER during eclipse project importer?

@snjeza
Copy link
Contributor

snjeza commented Feb 21, 2020

@testforstephen I agree. @fbricon What do you think?

@marlonpatrick
Copy link

marlonpatrick commented Jul 24, 2020

I had the same problem when not using the properties:

   <properties>
     <maven.compiler.source> XX </maven.compiler.source>
     <maven.compiler.target> XX </maven.compiler.target>
   </properties>

As I'm experimenting with Java 14 the way to configure the java version in maven has changed to:

<plugin>
  <artifactId> maven-compiler-plugin </artifactId>
  <configuration>
    <release>14</release>
  </configuration>
</plugin>

Thus, from the point of view of maven, it is no longer necessary to use maven.compiler.target/source, however, for VS Code it is still necessary to specify these properties so that it correctly interprets the version of Java used in the project.

Then, I solve my scenario using this two settings above.

@lincolnthree
Copy link

Well hello there :)

It does seem that VSCode-Java stuggles to properly detect and apply maven compiler settings from maven's pom.xml.

I've tried a number of configurations, and no matter what I do, the Java version defaults to 1.6 in org.eclipse.jdt.core.prefs. It can, however be manually configured, as pointed out earlier in this thread.

This matter is made worse because the vscode-java plugin will overwrite manually configured settings back to 1.6 when updating project configurations, making this supremely disruptive.

I also had to to set configurations manually in the .classpath file manually:

	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
		<attributes>
			<attribute name="maven.pomderived" value="true"/>
		</attributes>
	</classpathentry>

@snjeza
Copy link
Contributor

snjeza commented Dec 19, 2020

@lincolnthree could you attach your project or pom.xml?

@lincolnthree
Copy link

Update. Looks like adding a newer version of the maven-compiler-plugin and setting the following configuration has gotten things mostly working:

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>

@lincolnthree
Copy link

The broken version was maven-compiler-plugin:3.2.0

@lincolnthree
Copy link

lincolnthree commented Dec 19, 2020

Perhaps a warning could be issued if using an obsolete/incompatible version of the maven-compiler-plugin.

@tarilabs
Copy link

I have the same problem on a project with mixed JDK 8 and JDK 11/17 for its module.
Seems solved by applying same solution as in #1290 (comment)

e.g.: not enough

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

but this works:

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

I am using

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.10.1</version>
        </plugin>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants