I'm developing for a project which is compiled for Java 7.
In this project I use OkHttpClient v3.12.13, which is compatible for Java 7 (as stated here). However these lines produces an error in the Eclipse editor:
private static final OkHttpClient GLOBAL_OK_HTTP_CLIENT = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.build();
The error is this:
The type java.time.Duration cannot be resolved. It is indirectly referenced from required .class files
This error is only shown by the editor. Indeed, when I compile my project using CLI (outside Eclipse) I don't get any error for that implicit reference to the java.time package.
I'm aware that in Java 7 there is no java.time package. Indeed, I'm not using it in my code, it's just implicitly referenced by the OkHttp library (as the error message says).
Is there a way to fix this error on Eclipse?
This is how I configured compiler compliance on Eclipse:
Note that I can't upgrade to newer Java versions.
The java.time classes are built into to Java 8 and later. You are deploying your app to Java 7. That version of Java lacks the java.time.Duration class invoked by your code calling a library.
You claim that library supports Java 7. If that is true, the library must have a switch to avoid using classes not available in Java 7.
You have improperly configured your IDE to allow programming in a later version of than the version on which you deploy. That is a problem you should fix. If deploying on Java 7, then compile for Java 7. See Question, how do I get eclipse to use a different compiler version for Java?.
Of course, the best solution is to migrate to a modern version of Java. Java 7 reached end-of-life in 2015-04. I highly recommend moving to a long-term support (LTS) version. Currently that would be Java 8 and Java 11.
If it were your own code using the java.time classes, I would suggest adding the ThreeTen-Backport library to your project. That library provides most of the java.time functionality with nearly identical API for use with Java 6 and Java 7. But I am guessing that would not satisfy your library in question, though you might want to verify.
Same issue I was facing, Changing the version of selenium in pom.xml worked for me. Changed version from 4.1.0 to 3.141.59
I'm learning Camel by the book of Claus Ibsen and I would like to have your advise on this.
I have got the book and the code from the side.
In chapter1 it says run:
C:\camelinaction-master\chapter1\file-copy>mvn compile exec:java -Dexec.mainClass=camelinaction.FileCopierWithCamel
The error it produces is:
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1.1:java (default-cli) on project chapter1-file-copy: An exception occured while executing the Java class. null: InvocationTargetException: javax/xml/bind/annotation/XmlRootElement: javax.xml.bind.annotation.XmlRootElement -> [Help 1]
I'using
java 15.01 and
mavem 3.3.5
Since I got this issue at the very beginning of the book I thought before I start debugging the issue perhaps it is good to ask if the code from the book is still working or is it to old and not maintained? If that is not the case it is worth solving the issue otherwise is there newer learning material that you have used and good experience with?
The JAXB APIs are considered to be Java EE APIs and therefore are no longer contained on the default classpath in Java SE 9. In Java 11, they are completely removed from the JDK. (Quote from Java: How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException )
Try using Java 8.
UPDATE: As Claus (one of the authors of the book) pointed out, there are branches for Camel 3.x versions in the book source code repository:
https://github.com/camelinaction/camelinaction2/tree/camel37
3.x supports Java LTS versions: 8, 11, or 14, but does not officially support the non LTS Java versions.
As Kristof advised, short answer is use Java 8.
In addition to that, the Camel in Action book (2nd ed.) uses Camel 2.x and it supports only Java 8 so otherwise the sample code doesn't work.
If you really want to use later Java versions (11 and higher) you should use Camel 3.x (the latest version as of now is 3.7.1). Since it's a major upgrade you'd need to go through some migration work in order to make the sample code run with Camel 3.x. See the following official migration/upgrade guides for what to do:
https://camel.apache.org/manual/latest/camel-3-migration-guide.html
https://camel.apache.org/manual/latest/camel-3x-upgrade-guide.html
Thank you Claus Ibsen.
With the link to the new source files I'm able to continue my study.
https://github.com/camelinaction/camelinaction2/tree/camel37
I've just tried to run my app compiled using Java 8 on an Android 4.0 device. While I'm used to taking great care to look at the Android API levels in the Android documentation to make sure I'm only using APIs that are available on Android 4.0, I'm not so used to making sure I'm not using any features in Java itself that aren't available on Android 4.0.
Consider the following code, it tries to import the initializeScrollbars() API from View class because, for whatever reason, it has been removed from the official SDK:
try {
final Method initializeScrollbars = android.view.View.class.getDeclaredMethod("initializeScrollbars", TypedArray.class);
initializeScrollbars.invoke(this, a);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
While this code works fine on my Android 8.0 test system, it doesn't work on Android 4.0. The error is:
Could not find method java.lang.ReflectiveOperationException.printStackTrace
After some research I found out that ReflectiveOperationException is not available before Java 7 and so, apparently, Android 4.0 does not support Java 7.
This makes me wonder: Is there an overview which clearly shows which Android versions come with which Java version? e.g. how can I find out the first Android version that supports Java 7? And how can I find out the first Android version that supports Java 8?
This really must be easy to find but I'm just failing to see it. Googling always leads to results in which people are asking about the Java versions supported by Android Studio, not by Android itself.
So, can anybody please shed some light onto this? I know it must be somewhere really obvious, but I don't seem to find it...
and so, apparently, Android 4.0 does not support Java 7.
By your definition, Android does not support any version of Java. The java and javax classes in the Android SDK do not exactly match any version of Java, whether a numerical version (e.g., 6, 7, 8) or whatever you want to consider Java SE/EE/ME to be.
Is there an overview which clearly shows which Android versions come with which Java version
In terms of language features (e.g., lambda expressions), quoting the documentation:
Android Studio 3.0 and later supports all Java 7 language features and a subset of Java 8 language features that vary by platform version
Here, "Android Studio" is really referring to the build tools that compile your source code and create the Dalvik bytecode. Current tools can support all Java 7 and a few Java 8 features on all versions of Android. Additional Java 8 features are only available on API Level 24+, usually because they rely upon certain classes that were only added to the Android SDK at that point.
But your concern seems to be with classes and methods, in which case there is no simple mapping of any Java version to any Android version.
Moreover, you are using reflection to hack into framework classes, which means your results will not only vary by Android version but by device model, as device manufacturers can and do change the implementation of framework classes.
From the "Supporting Older Versions" AOSP documentation found at https://source.android.com/setup/build/older-versions#jdk:
Supported versions
Android 7.0 (Nougat) – Android 8.0 (Oreo):
Ubuntu: OpenJDK 8
Mac OS X: JDK 8u45 or higher
Android 5.x (Lollipop) – Android 6.0 (Marshmallow):
Ubuntu: OpenJDK 7
Mac OS X: jdk-7u71-macosx-x64.dmg
Android 2.3.x (Gingerbread) – Android 4.4.x (KitKat):
Ubuntu: Java JDK 6
Mac OS X: Java JDK 6
Android 1.5 (Cupcake) – Android 2.2.x (Froyo):
Ubuntu: Java JDK 5
The documentation does not presently (Feb 2022) make any correlation between Android >=9.0 and JDK (that I could find); I suspect this has been overlooked since it does not appear that the setup documentation has been thoroughly updated since sometime prior to the Ubuntu 20.04 LTS release. It does mention that the latest master branch (Android 12.0.0_r32) comes with a prebuilts folder that has the necessary JDK in it.
Well I just started working on codenameone I have a quite decent experience with Java. My code is all good, got no problems although while compiling I get this: error: package java.time does not exist import java.time.LocalDate;
Yes I know LocalDate was introduced in Java8 so my netbeans is set on Java8 also my project.
Note that I'm using Lambda Expresions and streams in the project without any problem.
What can cause this?
Update: This bug is not only with my machine, tested on several machines that run Java 8 correctly (java.time is seen) with JavaFX application or simple Java applications still have same bug with Codenameone projects.
In NetBeans you need to choose Java8 in order to use Java8 features. It is not enough to only have Java8 installed.
Finally I came to a fair answer. Codenameone is not compatible with all java 8 features. See here for more details.
Find Java Dependencies -> JDK 1.8 (Default) -> rt.jar at your Projects frame in Netbeans. You should see java.time package under rt.jar. If not, there is something wrong with your Netbeans or JDK installation.
You can also check Tools -> Java Platform to make sure Java 8 is correctly configured with Netbeans.
Just wondering if anyone has tried using new Java 7 language features with Android?
I know that Android reads the bytecode that Java spits out and turns it to dex. So I guess my question is can it understand the bytecode of Java 7?
If you are using Android Studio, the Java 7 language should be enabled automatically without any patches. Try-with-resource requires API Level 19+, and NIO 2.0 stuff are missing.
If you can't use Java 7 features, see #Nuno's answer on how to edit your build.gradle.
The following is for historical interest only.
A small part of Java 7 can certainly be used with Android (note: I have only tested on 4.1).
First of all, you could not use Eclipse's ADT because it is hard-coded that only Java compiler 1.5 and 1.6 are compliant. You could recompile ADT but I find there is no simple way to do that aside from recompiling the whole Android together.
But you don't need to use Eclipse. For instance, Android Studio 0.3.2, IntelliJ IDEA CE and other javac-based IDEs supports compiling to Android and you could set the compliance even up to Java 8 with:
File → Project Structure → Modules → (pick the module at the 2nd pane) → Language level → (choose "7.0 - Diamonds, ARM, multi-catch, etc.")
This only allows Java 7 language features, and you can hardly benefit from anything since a half of improvement also comes from the library. Features you could use are those which do not depend on the library:
Diamond operator (<>)
String switch
Multiple-catch (catch (Exc1 | Exc2 e))
Underscore in number literals (1_234_567)
Binary literals (0b1110111)
And these features cannot be used yet:
The try-with-resources statement — because it requires the non-existing interface "java.lang.AutoCloseable" (this can be used publicly in 4.4+)
The #SafeVarargs annotation — because "java.lang.SafeVarargs" does not exist
... "yet" :) It turns out that, although Android's library is targeting for 1.6, the Android source does contain interfaces like AutoCloseable and traditional interfaces like Closeable does inherit from AutoCloseable (SafeVarargs is really missing, though). We could confirm its existence via reflection. They are hidden simply because the Javadoc has the #hide tag, which caused the "android.jar" not to include them.
There is already as existing question How do I build the Android SDK with hidden and internal APIs available? on how to get those methods back. You just need to replace the existing "android.jar" reference of the current Platform with our customized one, then many of the Java 7 APIs will become available (the procedure is similar to that in Eclipse. Check Project Structure → SDKs.)
In additional to AutoCloseable, (only) the following Java 7 library features are also revealed:
Exception chaining constructors in ConcurrentModificationException, LinkageError and AssertionError
The static .compare() methods for primitives: Boolean.compare(), Byte.compare(), Short.compare(), Character.compare(), Integer.compare(), Long.compare().
Currency: .getAvailableCurrencies(), .getDisplayName() (but without .getNumericCode())
BitSet: .previousSetBit(), .previousClearBit(), .valueOf(), .toLongArray(), .toByteArray()
Collections: .emptyEnumeration(), .emptyIterator(), .emptyListIterator()
AutoCloseable
Throwable: .addSuppressed(), .getSuppressed(), and the 4-argument constructor
Character: .compare(), .isSurrogate(), .getName(), .highSurrogate(), .lowSurrogate(), .isBmpCodePoint() (but without .isAlphabetic() and .isIdeographic())
System: .lineSeparator() (undocumented?)
java.lang.reflect.Modifier: .classModifiers(), .constructorModifiers(), .fieldModifiers(), .interfaceModifiers(), .methodModifiers()
NetworkInterface: .getIndex(), .getByIndex()
InetSocketAddress: .getHostString()
InetAddress: .getLoopbackAddress()
Logger: .getGlobal()
ConcurrentLinkedDeque
AbstractQueuedSynchronizer: .hasQueuedPredecessors()
DeflaterOutputStream: the 3 constructors with "syncFlush".
Deflater: .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .deflate() with 4 arguments
That's basically all. In particular, NIO 2.0 does not exist, and Arrays.asList is still not #SafeVarargs.
EDIT: At the time this was written, the latest release was Android 9 and Eclipse Indigo. Thing have changed since then.
Practical answer
Yes, I have tried. But this is not a great test as the compatibility was limited to level 6 with no way (no simple way at least) to really use java 7:
First I installed a JDK7 on a machine that had no other JDK installed - Eclipse and Android are not installed either:
Then I installed a brand new Eclipse Indigo and checked it was actually using the JDK 7 (well, as this is the only one and as this is the one I've selected I would have been surprised)
Then I installed the latest version of the Android SDK (EDIT: Honeycomb, API13, at the time this post was written). It found my JDK 7 and installed properly. The same for ADT.
But I had a surprise when trying to compile and run a Hello Word Android app. The compatibility was set to Java 6 with no way to force it to Java 7:
I tried with a non-Android project, a regular Java one, and I had the explanation. The compatibility level seems to be limited by Eclipse (see the message at bottom of the following image):
So I had Hello World working, and also other apps, more complicated and using SQLite, Listview, Sensor and Camera, but this only proves that the compatibility handling of Java 7 seems to be well done and working with Android.
So, did someone try with the good old Ant, to bypass the Eclipse limitation seen above?
Theroetical answer
Anyway, the SDK is designed to be used with Java 5 or 6, as explained here.
We may have something working with Java 7, but it would be working "by accident". The building of the DEX may work properly or not, and once the DEX built, it may work or not. This because using a non-qualified JDK gives unpredictable results by definition.
Even if someone has succesfully built an Android app under plain Java 7, this does not qualify the JDK. The same process applied to another application may fail, or the resulting application may have bugs tied to the use of that JDK. Not recommended.
For those who are involved on webapps development, this exactly the same as deploying a web application built under Java 5 or 6 under an application server qualified for Java 4 only (let's say Weblogic 8 for example). This may work, but this is not something that can be recommended for other purposes than trying.
Quote from dalvikvm.com:
dx, included in the Android SDK, transforms the Java Class files of Java classes compiled by a regular Java compiler into another class file format (the .dex format)
That means, the .java source file does not matter, it's only the .class bytecode.
As far as I know, only invokedynamic was added to the JVM bytecode in Java 7, the rest is compatible to Java 6. The Java language itself does not use invokedynamic. Other new features, like the switch statement using Strings or the multi-catch are just syntatic sugar and did not require byte code changes. For example, the multi-catch just copies the catch-block for each possible exception.
The only problem should be that the new classes introduced in Java 7 are missing in Android, like AutoCloseable, so I'm not sure if you can use the try-with-resources feature (somebody tried it?).
Any comments on that? Am I missing something?
As of the Android SDK v15, along with Eclipse 3.7.1, Java 7 is not supported for Android development. Setting the source compatibility to 1.7 mandates setting the generated .class file compatibility to 1.7, which leads to the following error by the Android compiler:
Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tools > Fix Project Properties.
To expand on the above answer by #KennyTM, if you are targeting 4.0.3 and above (minSdkVersion=15), you can use the hidden APIs by adding a few classes to your target's SDK android.jar.
Once you do this, you can use try-with-resources on any Closeable, as well as implement AutoCloseable in your own classes.
I've made a zip containing sources and binaries of all the classes that needed to be modified in android.jar to make these APIs available. You just need to unpack it and add the binaries to your android-sdk/platforms/android-NN/android.jar
You can download it from here: http://db.tt/kLxAYWbr
Also of note is that, in the past couple of months, Elliott Hughes has made a few commits to the Android tree: finished off AutoCloseable, added SafeVarargs, unhidden various APIs, fixed Throwable's protected constructor and added support for version 51 class files in dx. So, there is finally some progress going on.
Edit (April 2014):
With the release of SDK 19 it is no longer necessary to patch android.jar with the additional APIs.
The best method to use try-with-resources in Android Studio for an app that targets 4.0.3 and above (minSdkVersion=15) is add the following compileOptions to your build.gradle:
android {
compileSdkVersion 19
buildToolsVersion '19.0.3'
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
Android Studio will complain that try-with-resources can't be used with this API level, but my experience is that it can. The project will build and run without issue on devices with 4.0.3 and above. I've experienced no issues with this, with an app that has been installed into 500k+ devices.
To ignore this warning, add the following to your lint.xml:
<issue id="NewApi">
<ignore regexp="Try-with-resources requires API level 19"/>
</issue>
It seems that getting this to work with pure ant is a bit of a kludge.
But it worked for me: http://www.informit.com/articles/article.aspx?p=1966024
In order to use Java 7 features in code build by Android's ant based build system, simply put the following in your custom_rules.xml in your projects root directory:
custom_rules.xml:
<project name="custom_android_rules">
<property name="java.target" value="1.7" />
<property name="java.source" value="1.7" />
</project>
Some people might be interested in this git project I've found, that seems to allow to run Java 7 on android.
https://github.com/yareally/Java7-on-Android
However too much of a risk if I add this in the current project I work on. So I'll wait until Google to officially support Java 7.