When I compile any class that contains the Spring #org.springframework.web.bind.annotation.CrossOrigin annotation using maven from the command line, it compiles just fine. But, when I try to compile the same code using IntelliJ Idea 15, I get this weird error:
[ERROR] /Users/gregederer/devewx2/geoengine/src/main/java/geoengine/controller/rest/TimeSeriesController.java:[34,1] annotation org.springframework.web.bind.annotation.CrossOrigin is missing value for the attribute <clinit>
This could be related to https://community.oracle.com/message/4827054. But, that issue was never really resolved.
Any suggestions?
Try using JDK 1.7.0_80. I encountered this issue using JDK 1.7.0_79. Worked on 1.7.0_80 though.
I'm having the same problem... Excluding it from validation did not help in my case. When I compile it from cmd with mvn, everything works fine, but from intellij, it does not.
My intellij settings forced the use of java jdk 1.7 (needed for the project). When I set it to 1.8, I have no problems. I suppose this is a bug in javac 7 (see here).
I've encountered the (known and resolved in 1.8) problem with javac
failing on annotations with static final fields requiring complex
initialization. The failure manifests itself on the latest 1.7
I had the same issue while deploying my app in travis ci which had installed oracle jdk 1.7.0_76. I force-updated jdk7, then upgraded to jdk 1.7.0_80. The #CrossOrigin annotation did not complain after that.
After facing this issue today I also browsed through the Internet and couldn't find a straight answer. In my case using a higher Java version was not possible, because project was to be deployed to JDK 6. However in the end I found the solution, hope it will help someone else.
Key point is Java is backwards compatible.
That's the answer :) . You can use a higher JDK version like 1.7 or 1.8 to compile your project and use -target option to cross compile to lower version.
-target version
Generate class files that target a specified version of the VM. Class files will run on the specified target and on later versions, but not on earlier versions of the VM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), and 1.7 (also 7).
The default for -target depends on the value of -source:
If -source is not specified, the value of -target is 1.7
If -source is 1.2, the value of -target is 1.4
If -source is 1.3, the value of -target is 1.4
If -source is 1.5, the value of -target is 1.7
If -source is 1.6, the value of -target is 1.7
For all other values of -source, the value of -target is the value of -source.
Ref: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html
I was using Maven so I just had to change <java.version> property in the POM and that was it. I was still using Java 8, with the latest Maven however maven was cross compiling to JDK6.
You can exclude the error from being included in the validation through IntelliJ by right clicking it and then it should compile.
Edit: It appears updating the JDK is the appropriate fix, my suggestion was intended to quickly bypass the issue and was more of a bandaid fix as the validation error should not have affected anything. See Nikki's answer for her explanation.
Related
I want to recompile an old jar file (which was compiled in java 1.2). So that there are no errors i need to compile it in Java 1.2 aswell. But havent found a jdk 1.2 which i can install on windows 7 (and 64bit).
Any suggestions?
thanks in advance!
Yes, you can set the version of compiler at compile time. And compile your java code into old versions of java.
From Oracle article : http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javac.html
Cross-Compilation Example
Here we use javac to compile code that will run on a 1.4 VM.
% javac -target 1.2 -bootclasspath jdk1.2/lib/classes.zip \
-extdirs "" OldCode.java
There are two scenarios, just compiling old code and actually developing for an old JRE.
For just compiling you don't need an old JDK, you can adjust the target language level javac compiles with the -target option (see: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html) - Although there may be edge cases that may break the compiled code if the compiler decides to select a different overload for a method that does not exist in the old JRE.
For developing old JRE compatible code, you could use above method but you run the risk accidentially using an API that isn't present in the real old JRE. To avoid that problem you need the actual 1.2 API, meaning you need the rt.jar file from a real 1.2 JRE/JDK. This can be added into your project in your IDE (and the current e.g. 1.8 JDK removed). The detailed procedure how to set this up depends on the IDE. Likewise the 1.2 rt.jar can be provided to javac, also using command line switches. Again you need no runnable 1.2 JRE to compile/develop.
I'm trying to consume a third-party API, where I get support for the third party API upto JDK 1.6.
I have other few projects which are built using JDK 1.7 and as part of the product I'm also packaging JRE 1.7.
if compiler compliance level is set to JDK 1.6, compile & run using JDK 1.7 libraries produce same result as of compile & run using JDK 1.6?
Would it be safe to claim support from third-party vendor when compiler compliance level is set to JDK 1.6.
Update:
I presumed that setting compiler level in eclipse is same as setting -source & -target options of javac.
I'm not sure if compiling using JDK 1.7 setting source & target to 6/1.6 is same as compiling in jdk1.6.
The problem is in changes of Java API between versions. There are some classes and methods that are available in Java 7 but not in Java 6 and other way round. The code compiles with Java 7 but it will not run with Java 6 because of missing classes or methods.
Unless you compile with Java 6 JDK, you cannot be 100% sure.
Yes, if you compile with compliance level set to 1.6, it will be able to run on java 6 - compiler will guarantee that. It should be able to run on java 7 as well, since JRE is backward-compatible.
You can actually specify the .class files version compatibility in the "Preferences->Java->Compiler" (project specific), so at worst you are benefitting from a more recent compiler building probably exactly the same bytecode as using JDK 1.6.
"Compliance 1.6" however does not ensure that you get exactly the same result as using JDK1.6, but java standard ensures applications built with 1.6 will run the same on a >= 1.6 JRE.
So if you are really afraid of incompatibilities, build the project (on your CI server I suppose) with a project specific setting 1.6 on a machine with both JRE 1.6 for this one, and 1.7 for other projects, and bundle a 1.7 in your distribution, it is guaranteed to run ok by Sun/oracle/java.
i.e. if the code is built with JDK 1.6, and used by other JDK >= 1.7 code you are fine with respect to versioning. Probably this is the case of many jars you use everyday.
However, building the code that is stamped 1.6, with a real JDK 1.6 is the only sensible thing to do if you are afraid of real world problems (money involved).
So I think then you are safe to "claim support", build in 1.6 and use the jar in 1.7.
In my experience with Eclipse, Compliance level set to Java 5 is not the same as compiling with JDK5. It has allowed Java 6 methods to pass compilation locally when the Installed Java was set to Java 6 and the compliance was set to 5 and then our build failed when the files were checked in.
This behaviour appeared strange me. The following is what happened:
We have a build.xml file for Ant, which says <javac source="1.5" target="1.5"></javac>.
We have updated Java on our system (Linux) to 1.6, but we forgot to update the Ant build.xml file.
Ant building is happening successfully, How is it happening? Is it like the higher version of Java can downgrade to lower versions? Or if Ant cannot find the version of Java specified it uses the default version?
There will not be any problem in upgrading JDK in this scenario
<javac source="1.5" target="1.5"></javac>
Means that it tells Java compiler that source is written using Java 1.5 and it should create the target build suitable for Java SE 1.5 environment.This is really possible with newer JDK.This is exactly the same as
javac -source 1.5 -target 1.5
Please refer the documentation of the javac tool
Hope this helps
These options are passed on to the Java compiler. It can generate byte code for older JVMs (target) and it can also accept source written for older Java versions (source). This makes for example sense, when a new Java version introduces new keywords but you use that word as identifier in your source.
It will generate the byte code of JDK 1.5 instead of JDK 1.6, because Java supports backward compatibility so byte code of JDK 1.5 could easily run on JDK 1.6 JRE.
I am currently working in jdk 1.5 version. I want to compile and execute code in jdk 1.6 version.
How can i do this?
It's a bit unclear what you're asking.
If you're asking whether you can compile code with JDK 1.5 and run it with JDK 1.6, yes, that's fine. 1.6 can run code compiled with 1.5 without trouble. You won't be able to make use of any of the Java 6 (1.6) compile-time or API enhancements, of course. To do that, you'd have to compile with the 1.6 (or higher) JDK.
If you're asking how to start using 1.6, just install it and start using it. (That's a very general and somewhat vague answer, but then, it's a very general and vague question.)
Use the -target and -source flags to tell the compiler what source version you are using or what target version you plan to run it on
javac -target 1.6 -source 1.5 [classes to compile etc]
http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javac.html#options
Install JDK 1.6 and re-set your JAVA_HOME variable. Normally, the code from the older platform versions will work on newer ones.
if you are using an IDE, there must be an option with the location of java compiler, change to the directory of your installation of your new jdk.
else, change the value of your environement variable JAVA_HOME to the directory of your installation of your new jdk.
you don't have any change to do in your code
jdk 1.6 supports all features present in jdk 1.5.So u can compile and run your program on jdk1.6 without any problem.
Java is backwards compatible, so you can compile and run your application on 1.6 without any problems but maybe with some warning messages on compile.
You can use also the arguments -target and -source. More info here
Have a look at the java documentation about compatibility issues.
Find here
When using the Java compiler (javac), we can specify two kinds of compatibility. One is using -source and the other is using -target. What is the difference between these two?
For example, -source 1.5 and -target 1.6?
Also, is there any case where we use a different source and target compatibility level?
From the javac docs:
-source Specifies the version of source code accepted.
-target Generate class files that target a specified version of the VM. Class files will run on the specified target and on later versions, but not on earlier versions of the VM.
In your example:
-source 1.5 and -target 1.6
This would be used to make sure that the source code is compatible with JDK 1.5, but should generate class files for use on JDK 1.6 and later.
Quite why you would do this is another matter.
The -source indicates what level of compliance your source code has: are you using Annotations? Then you would need at least 1.5; are you using #override on interface implementations, you would need 1.6 etc
The -target specifies what Java version you want to be able to run your classes on. You could use a Java SE 7 compiler and compile to run on Java SE 1.5.
This is mostly useful to produce a jar file working with an older version of Java.
I believe that so far all JDKs are able to execute older version too, so there is no real reason to have target larger than source.
It does however make sense to set target to e.g. 1.6 when using a 1.7 JDK.
I'm not sure, but I believe it could work in some situations to compile a 1.7 java code using a 1.7 compiler to a 1.6 jar, for example expressions such as
ArrayList<Integer> foo = new ArrayList<>();
that are only valid in 1.7+ source version should compile to 1.6 compatible byte code. But I have not verified whether the compiler will actually do this. Unfortunately, this doesn't seem to be implemented in practise.