JavascriptInterface annotation for JELLY_BEAN and below - java

As clearly noted on official docs, usage of #JavascriptInterface is needed for API level JELLY_BEAN_MR1 and above, to access a java function from the webview side.
This means that Project Build Target must point to API 17 or above which resolves the following import:
import android.webkit.JavascriptInterface;
How does android handles this code for API 16 and below? Will I get a runtime exception or does it ignore this import on runtime?

I'm quite surprised with these answers... they are not accurate.
If you add the JavascriptInterface and another annotation lets say MyAnnotation to the same method(like I did), and then try to access the MyAnnotation instance annotation then you are in for a ClassDefNotFoundException surprise!
My solution which seems to work for now (it has been more than a year), is to add the annotation declaration to the application project:
package android.webkit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD})
public #interface JavascriptInterface {}
This solved the problem on 2.3.5, and still worked on 4.3 and 4.4 and 4.2.
Hope this helps someone else!

The annotation class JavascriptInterface is not loaded by older Android versions, so your code will run without any issue on older versions.

Imports like the one you have suggested import android.webkit.JavascriptInterface; are only hints to the compiler so it can resolve the full class path you are referring to further on in your source. The VM will only throw a ClassNotFoundException when you try and use the class. So the simple answer is no, everything will be fine as long as you protect your use of the JavascriptInterface with something like the following.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
JavascriptInterface js = new JavascriptInterface(){ ... };
}

Related

Java how import order matters when import class/enum inner an inner class

Here is my class:
package pepelu;
import pepelu.ImportTest.InnerClass.InnerEnum;
import javax.annotation.Resource;
public class ImportTest {
#Resource
public static class InnerClass {
public enum InnerEnum {
A
}
}
public static void main(String[] args) {
System.out.println(InnerEnum.A);
}
}
When I use maven to build, it will give a compilation error:
mvn clean compile
[ERROR] /Users/finup/Desktop/a/importtest/src/main/java/pepelu/ImportTest.java:[8,6] cannot find symbol
After changing the import order to:
import javax.annotation.Resource;
import pepelu.ImportTest.InnerClass.InnerEnum;
I got a successful maven build.
I searched for documents, but cannot find an explain for this.
Could anyone please explain how import works in this case?
I guess the reason is a "circular" dependency: you have some element X that you import within the same file/class where you are defining it.
Meaning:
import pepelu.ImportTest.InnerClass.InnerEnum;
actually refers to code following in the very same file:
public static class InnerClass {
public enum InnerEnum {
This means: for the compiler, in order to process that import, it has to look into the body of the class in the same file.
It seems that javac does that "immediately". Meaning: it starts reading import statements, and importing from the same class makes it "suspend" looking at imports, but checking out the following class definition.
And guess what: that class definition makes use of another import. In order to "process" the definition of that enum, the compiler needs to understand where/what that #Resource annotation is about. But it doesn't know the annotation yet (because the compiler didn't see the import, yet).
When you change the order, the compiler understands that #Resource usage in the class definition.
And of course: the real answer is not to reorder imports. The real answer is to not import something from the class that is following after the import statements. There is absolutely no point in doing so.
Edit, given the comment by the OP about how this can work in Redisson: honestly, I don't know. It might depend on how exactly that class is compiled. Maybe such code works with newer (or older) versions of javac, maybe this works with specific versions of the eclipse or intellij or xyz compiler.
Meaning: I gave you an explanation why you are running into this problem. That doesn't mean that any compiler must necessarily run into the same problem.

Can't import the java.util.function.*;

I am trying to use the java.util.function.*; so that I can use the Predicate interface. But my NetBeans says that the import package does not exist. Also, my Netbeans wants to import java.sql.rowset.Predicate; for the Predicate interface, which has nothing to do with what I need the interface for. I am using the interface so that I can pass a function or lambda expression through a parameter. According to my Netbeans, I have no updates and my version is 8.0.2, can anyone help please?
import java.util.function.*;
public class NumberingLogic {
public boolean checkX(Predicate<Integer> predicate){
return result;
}
}
Predicate is a functional interface which was added in java 8. You need to install java 8 and point your netbeans to this installation.
You can do it through through the IDE itself: please see following tutorial for details (this is an official documentation).
Or you can also change through the IDE configration files by adding netbeans_jdkhome parameter in %NETBEANS_HOME%\etc\netbeans.conf e.g.
netbeans_jdkhome="d:\Program Files\Java\jdk1.8.0_121"

import android_view_TextureView not found

i can't import android.view.TextureView.
All other import work except android.view.TextureView. i download the textureView.java but can't compile, because of other unknown type like private HardwareLayer mLayer.
i see that every body import it without any error.
TextureView was added in API level 14. In order to use it, you must target your app to at least this API level.

incompatible types found: required: default enums in annotations

[javac] C:\ws\galileo\test\Cacheable.java:13: incompatible types
[javac] found : com.io.CacheType
[javac] required: com.io.CacheType
[javac] public CacheType id() default CacheType.COMMON;
I really don't get this one.
I have a project where I'm custom building a caching interceptor for Spring. It simply is a look by cache name to point to EhCache and uses aop-autoproxy to load the CacheableAspect (which is my caching intercepter). Now when I use the default value in the annotation, ANT gives me the compiler error below. I tried updating to the latest JDK (i'm on 1.6 16 now) and setting source/target levels in the ant script but no success. When I remove the default value and force all areas to specify a value, it compiles in ant fine.
It always worked in Eclipse, I had unit tests that ran perfectly with the previous default value.
What gives? I tried building a project (no spring) that simply echoed the configuration with ant and it compiled in ant fine (and in eclipse).
that tells me MAYBE it might be the spring auto-proxying somehow? but then why would the compiler not give me the generated type name? GRRRR. Any thoughts?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.io.CacheType;
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD})
public #interface Cacheable {
public CacheType value() default Cachetype.COMMON;
}
public enum CacheType {
COMMON("common"),
PERSISTENT("persistent";
private String cache;
CacheType(String cache) {
this.cache = cache;
}
public String cache() {
return this.cache;
}
}
Still present in JDK 6u25, but adding package to default value does the trick:
CacheType value() default com.io.CacheType.COMMON;
Have a look here:
http://bugs.sun.com/view_bug.do?bug_id=6512707
this might be the cause of your problem.
So just a little update. While the bug tracker shows the bug as closed and seems to want to refute any new openings of the bug. When I encountered this bug in this example revolves around the compile time annotation processor. Since the retention is RUNTIME which means it does not require a compile time annotation processor it appears that the compile time annotation processer is blowing up the compile process. Whenever I am in NetBeans and I have compile time annotations enabled under Build->Compiling in the projects properties I receive a nebulous series of errors.
I am going to attempt opening a new bug ticket for the issue and just thought I would pass on the easy workaround for now.
Still present using javac 1.6.0_26. yurez's workaround of using the fully qualified type name when specifying the default value still works.
Found this bug is solved in 1.6.0_31 and 1.7.0_03 (maybe also in some previous versions), so just upgrade the java compiler.
I wonder if it this is caused by defining Cacheable and CacheType in the same source file, and then importing "com.io.CacheType". That could conceivably make the compiler think that there are two classes called "com.io.CacheType".
Could you post the entire source file or something? The code you posted seems copy/pasted from different source files and is full of typos.
Normally the following should always do the trick when CacheType enum is in a different source file, you had a typo in CacheType.COMMON:
public #interface Cacheable {
public CacheType value() default CacheType.COMMON;
}
Works with a Fully qualified type name.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.io.CacheType;
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD})
public #interface Cacheable {
public CacheType value() default com.io.Cachetype.COMMON;
}

Suppress deprecated import warning in Java

In Java, if you import a deprecated class:
import SomeDeprecatedClass;
You get this warning: The type SomeDeprecatedClass is deprecated
Is there a way to suppress this warning?
To avoid the warning:
do not import the class
instead use the fully qualified class name
and use it in as few locations as possible.
Use this annotation on your class or method:
#SuppressWarnings("deprecation")
Since Java 9, you might need to add:
#SuppressWarnings("removal")
If the class was annotated with something like:
#Deprecated(since = "3.14", forRemoval = true)
As a hack you can not do the import and use the fully qualified name inside the code.
You might also try javac -Xlint:-deprecation not sure if that would address it.
I solved this by changing the import to:
import package.*
then annotating the method that used the deprecated classes with#SuppressWarnings("deprecation")
Suppose that you are overriding/implementing an interface with a deprecated method (such as the getUnicodeStream(String columnLabel) in java.sql.ResultSet) then you will not get rid of deprecation warnings just by using the annotation #SuppressWarnings( "deprecation" ), unless you also annotate the same new method with the #Deprecated annotation. This is logical, because otherwise you could undeprecate a method by just overriding its interface description.
you can use:
javac FileName.java -Xlint:-deprecation
But then this will give you warnings and also tell you the part of the code that is causing deprecation or using deprecated API. Now either you can run your code with these warnings or make appropriate changes in the code.
In my case I was using someListItem.addItem("red color") whereas the compiler wanted me to use someListItem.add("red color");.
If #SuppressWarnings("deprecation") is not working for you like for me. You can find exact squid number in sonar lint plugin. And then you can simply suppress warning: #SuppressWarnings("squid:CallToDeprecatedMethod")

Categories

Resources