When i compiled my application in blackberry it shows the following error.
generics are not supported in -source 1.3
(use -source 5 or higher to enable generics)
how to solve this
Java 1.3 is barbaric and no one should ever have to suffer its indignities. Fortunately, there is a solution!
Generics, enums, changing return signature in overrides, and pretty much everything that makes java usable was introduced in java 1.5. (see http://en.wikipedia.org/wiki/Java_version_history). Fortunately, most of java 1.5 was designed to be backwards compatible and not require JVM / bytecode changes. (or maybe this was unfortunate, as it lead Java's implementation of generics to be much weaker than C#. just try creating a generic class with static methods / fields that use the generic parameter)
This IBM article does a good job of explaining the background:
http://www.ibm.com/developerworks/java/library/j-jtp02277.html
But this JVM similarity allowed for creation of tools such as:
http://retrotranslator.sourceforge.net/
This is the section from my Ant buildfile that calls retrotranslator:
< java jar="${transformer.jar.exe}"
fork="true"
classpath="${epic-framework.dir}/tools/retrotranslator-runtime13-1.2.9.jar:${epic-framework.dir}/tools/retrotranslator-runtime-1.2.9.jar"
args="-srcjar ${build.dir}/classes5.jar -target 1.3 -destjar ${build.dir}/classes5to3.jar"
/>
Run the converted jar through preverify.exe and then give it to rapc.exe and you will have a working Blackberry app written with Java 1.5.
Edit: I missed a key detail in my original post. In addition to being Java 1.3, the Blackberry class hierarchy is missing many classes that would normally be a part of a Java SE 1.3 JDK. The one you will hit first is StringBuilder -- javac transforms ("string" + "otherstr" + "blah blah") into StringBuilder.append("string").append("otherstr").append("blah blah"). That class doesn't exist on BB, so you break. However, BB has StringBuffer, so writing an adapter between the two is pretty easy. The one catch is that BB disallows apps from adding classes into java.*. This can be very effectively fixed in the build process: 1) build your app against Java 1.5 w/ java.lang.StringBuilder on the classpath, 2) string transform java.lang.Stringbuilder (and everything else in your compat shim) to live in com.mycorp.java.lang.StringBuilder and build it into a JAR file. 3) Use that JAR file w/ retrotranslator and retrotranslator will update all bytecode references to java.lang.StringBuilder so that they now point to com.mycorp.java.lang.StringBuilder. Now you have a java 1.3 compatible bytecode that can be run on a Blackberry.
If anyone is interested in this stuff, contact me. I could look into open sourcing the compat library I have.
This is a limitation of J2ME, which uses a subset of the J2SE (no collections, reflection, etc.) and a Java language level of 1.3. Any code written for J2SE will most likely need to be manually ported.
It seems the JDK5 is not yet supported.
Same question was asked on the blackberrry forum but about enum support:
Sadly, the BlackBerry api is very behind in terms of Java versioning. There's no Generics, no Maps, no Enums - it's based around JDK 1.3.
I believe there is no way of enabling this feature within your BlackBerry app. If you find one, I'd be very interested to hear about it.
Related
Is it possible to parse Java files that are external to the eclipse environment? I have only realised operations related to obtaining an AST(s) from Eclipse file (or projects).
Does the current version of Rascal support Java 8?
Yes to the first question:
you could use lang::java::m3::Core::createM3FromDirectory, or read its definition and make your own version.
this code uses setEnvironmentOptions to the JDT's Java compiler for controlling the classpath and the sourcepath of the compiler.
there is no dependency on Eclipse as a whole
To the second question:
No: the current stable release is pre Java 8
Yes: the current unstable release should work for Java 8. There are no specific tests for this yet, so you may be in for some early adopter surprises.
I would like to know the minimum Android API level AndroidAnnoatations supports ? I could not find any info on their website .
regards,
Felix T
I think there is NO specific minimum Android API Level that AndroidAnnotations can work with.
Since it's a compilation tool, I mean it's related with the Java files and it's related not with Android API.
If you build an Android project with AndroidAnnotations, then some intermediate java files will be generated, which will be the final java file for Java compiler, and that's all. It's just used for convinience of your development. The generated apk file will not have information about AndroidAnnotations - it's something like a conversion tool (shorter exprssion to long complicated expression, which is not visible to you).
I think that you can use AndroidAnnotation from Android API Level 1.
Maybe some of the annotations cannot be used in Android API 1 project, but even if such case happens, just removing only that specific annotation in your .java file will make it work.
I have few own APIs with around 2000 classes overall. Some of them use the new Path API from JDK7. Most other classes, however, do not rely on any new JDK APIs or new language features. So most classes could be used in a JDK6 environment (which I plan to do). Let's assume, I've annotated all JDK7-only classes with #Java7Only.
What I need now, is a way to create a JDK6-only subset of all my projects more-or-less automatically, without introducing new version branching or product lines (would be too complicated to maintain).
All projects are created using Netbeans, thus using Ant. Many projects depend on others.
Please help me evaluate, which ideas according to my problem is most appropriate. Which problems could occur with each idea?
Common first step for all ideas
Let an annotation processor search for #Java7Only-annotated classes and store the list to a properties file.
Idea 1 (specific)
Write a tool which would use the properties file to recursively copy the whole project, except JDK7-only files.
Build the copied project using JDK6 by invoking ant, thus getting a JDK6-compliant jar.
Idea 2 (specific)
Write a second annotation processor which would use the properties file to pass everything except JDK7-only files to a JavaCompiler instance.
Either build a jar using Java APIs or use Ant API for that.
(This would be a Java-only idea, but probably too complicated)
Idea X (abstract)
Somehow influence the Ant build process (by overwriting some targets?) and for each JDK6-compliant class: let Ant compile two versions of it (one time with JDK6 compiler, another time with JDK7 compiler).
(JDK7-only classes would be compiled only once, using the JDK7 compiler, of course)
Package each bunch to a separate jar.
Possible common problems to the ideas
Some projects dependent on others, so some actions (such as packaging) should consider this.
Remember: the JDK7 compiler generates downward incompatible class files, that's why every possible idea has to happen on sources-level (before or during the build process, not afterwards).
My thoughts on Idea 2:
Essentially this is invoking a compiler within a compiler. Annotation processors are run as part of compilation. Can this be done safely? Is there any static state in Sun's javac that would cause problems. (I don't know the answer but from memory there might be some static state that could cause problems in this scenario).
Idea 1 seems simpler and better to me.
But taking a step back, is it possible to separate out all the JDK 7 specific stuff into a separate module and compile it separately, into a different JAR?
Have the 'main' project, compiled using JDK 6 (which JDK 7 would have no problems reading because it is backwards compatible)
The JDK 7 specific module(s), with source in a different directory, which includes the 'main' JAR on the compilation classpath, could be built separately, with a different build.xml if necessary.
This only partially applies but I'd thought I'd mention it anyway.
The problem with just using -source 1.6 -target 1.6 options for validation is that you can still use Java 7 API when compiled using JDK 7.
I've used the Animal Sniffer Maven Plugin for a few projects now and it has proved quite useful. This plugin scans byte-code of your classes for JDK API usage. That is, you can tell it to fail the build if you attempt to use JDK 7 API when you are targeting JDK 6. This wont help much for separating out classes as you need but it could be useful as a final validation step combined with -source 1.6 -target 1.6 compiler options.
There is also an animal sniffer Ant plugin, as mentioned from the Animal Sniffer main page.
Is this statement true:
com.sun.xml.internal package is an internal package as the name suggestes.
Users should not write code that depends on internal JDK implementation classes. Such classes are internal implementation details of the JDK and subject to change without notice
One of my colleagues used one of the classes in his code, which caused javac task in Ant fail to compile our project as the compiler couldn't find the class. Answer from Sun/Oracle says that this is expected behavior of the compiler as user shouldn't use the package.
Question is why the classes in the package made public in the first place?
Thanks,
Sarah
Sun classes in the JDK are prefixed sun.* and are not part of the public supported interface so should be used with care. From the Sun FAQ:
The classes that Sun includes with the
Java 2 SDK, Standard Edition, fall
into package groups java., javax.,
org.* and sun.. All but the sun.
packages are a standard part of the
Java platform and will be supported
into the future. In general, packages
such as sun., that are outside of the
Java platform, can be different across
OS platforms (Solaris, Windows, Linux,
Macintosh, etc.) and can change at any
time without notice with SDK versions
(1.2, 1.2.1, 1.2.3, etc). Programs
that contain direct calls to the sun.
packages are not 100% Pure Java. In
other words:
The java., javax. and org.* packages
documented in the Java 2 Platform
Standard Edition API Specification
make up the official, supported,
public interface.
If a Java program directly calls only
API in these packages, it will operate
on all Java-compatible platforms,
regardless of the underlying OS
platform.
The sun.* packages are not part of the
supported, public interface.
A Java program that directly calls
into sun.* packages is not guaranteed
to work on all Java-compatible
platforms. In fact, such a program is
not guaranteed to work even in future
versions on the same platform.
It's because Java visibility modifiers (especially at the type level, where there are only two options) don't currently have the granularity to achieve the sort of visibility you're hinting at. I don't know the specifics of the internal class or classes you're using, but basically making the classes private would have made them unfit for their intended purpose, so the only other choice was public.
Sadly JAXB (bundled with Java6) seems to rely on a non-public class "com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper" to allow you to specify namespace prefixes when marshalling to xml.
You have to really go out of your way to get this compiling with ant:
http://pragmaticintegration.blogspot.com/
Summary:
Option 1.
Add jre libs as bootclasspathref
Add property: includeJavaRuntime="yes"
Option 2.
Use JAXB-RI libs - change property to "com.sun.xml.bind.marshaller.NamespacePrefixMapper"
Also mentioned here:
Define Spring JAXB namespaces without using NamespacePrefixMapper
Will code compiled using 1.5 and 1.6 run on a 1.4 JRE? We weren't sure which Java versions the 1.4 JRE supports.
We know that if the code in question implements 1.5 or 1.6 supported features then it definitely won't compile... and that there are some risks with "backwards compiling" but wasn't sure if the 1.4 JRE would refuse to even load the 1.5/1.6 compiled classes or not.
Update: I confirmed you get a java.lang.UnsupportedClassVersionError exception if you run an 1.6 class file on JRE 1.4.
You can cross-compile. This document shows you how:
http://java.sun.com/javase/6/docs/technotes/tools/solaris/javac.html#crosscomp-example
You must specify the specific major version you're targeting (1.4, it sounds like).
Using this technique, your best bet is to always use the newest javac you can find! That way you have all the latest bug fixes and performance improvements, and it's perfectly safe.
EDIT: note that this does address the problem of library incompatibilities, which was discussed in several answers!
Only if you compile with javac -target 1.4 switch.
Obviously you will not be able to use 1.5+ features, such as Generics, Executors, etc.
If you just build with the defaults of javac 1.6, your class files will not work on old versions of Java.
The best way to compile for older Java is just to use the older JDK releases. But if you really want to try to compile for older Java from newer, here are some instructions:
How to cross-compile for older platform versions
Source, target, class file version decoder ring
You also might be interested in http://en.wikipedia.org/wiki/Java_backporting_tools
I don't think it will.
Occasionally (for reasons too complicated to explain), I try to run code in a 1.5 JRE that I compiled in a 1.6 JDK. It typically throws a java.lang.UnsupportedClassVersionError exception.
Yes and no. You can run code compiled under Java 6 on a 1.4 jvm if you set the "source" and "target" javac options to the version you are targeting (e.g. 1.4) when you compile them. This will work in cases where you have not used any of the additional classes or language features that were added since the target version.
Good luck.
Yes, you can produce class files that are compatible with 1.4 with the 1.6 compiler (javac) however, simply doing this is not necessarily going to produce code that will work. The problem is that that will still compile against the 1.6 version of the API.
At first glance you would not expect this to be a problem since the contracts should not change but it is - I had a problem in that a new constructor that takes IIRC an integer was added to BigDecimal (in 1.5) and so at compile time the call to that constructor was specified however at runtime that constructor did not exist and so a runtime exception. You're probably going to have issues like this when methods are overloaded and you're relying on auto variable conversion.
The Javac app is in fact independent of the version of Java that it belongs to - you can specify a different API to use against 1.6 javac and in order to obviate any runtime issues this should be done.
Java 1.5 was a major release where it introduced enums,autoboxing and other stuffs.while compiling you will get exception saying unsupported class version.But if you compile with the command javac -source 1.4 -target 1._ claasname.java it will compile.
If you are using features of 1.5 like auto boxing and enums in that scenario it won't compile since these features are not available in 1.4.In this case we need to convert our code to older versions based on some tools.