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

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"

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.

How to import a function from a Java classes static method drools 6.5

I'm having trouble getting the function importing to work from Java class to drools DRL. For example with the following DRL:
package rules
import com.company.my.Person;
import function com.company.my.FunctionUtility.allowVote;
dialect "java"
ruleflow-group "PersonRules"
rule "person can vote"
when
$p:Person(age > 17)
then
allowVote();
end
referencing imported Java Function:
public class FunctionUtility {
public static void allowVote(){
System.out.println("Voting allowed");
}
}
I'm getting the following error when doing mvn clean install:
The method allowVote() is undefined for the type Rule_Person_Can_Vote
Only a type can be imported. com.company.my.FunctionUtility.allowVote resolves to a package
This stackoverflow question had a similar ask, but their solution is not consistent with the drools documentation or this 6.5.0 unit test for importing functions and doesn't work for me in any case.
Has anyone gotten function imports to work with drools 6.x, and if so how did you do it?

Why do I get "Type okhttp3.Call does not have type parameters" when using Retrofit2?

I am trying to follow this tutorial for Retrofit2 Getting Started and Create an Android Client.
The imports are fine
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
and I can follow the tutorial fine except for one thing. I am trying to create the GitHubService Interface and I run into two problems: The Call<V> says that it doesn't take any type parameters and I am also unsure where to put the Contributor class since it's according to the tutorial only declared as static, does that mean it's nested somewhere?
import okhttp3.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
public interface GitHubClient {
#GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
#Path("owner") String owner,
#Path("repo") String repo
);
}
static class Contributor {
String login;
int contributions;
}
I have the Contributor class in a separate file and have it as public.
Also, the Call class does not import automatically in Android Studio, I have to select it manually, but it's the only Call I got (except for Androids phone api)
Please help me with why I get this errors, from what I can see there is no one around with the same thing so I am missing something fundamental.
Accordingly to the compile time error you are getting you did import Call from the wrong package. Please, check your import and be sure that you have
import retrofit2.Call;
everything Retrofit related import should be from the package retrofit2.
On the other hand
Call contributors(
it can't guess what you want to return. A Contributor ? a List<Contributor> maybe? E.g.
public interface GitHubClient {
#GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
#Path("owner") String owner,
#Path("repo") String repo
);
}

JDiagram older version throwing StackOverflowError with JRE 8 at ExtendedArrayList.sort

I'm using JDiagram JAR like below
Diagram myDigram = new Diagram();
myDigram.routeAllLinks();
This code works fine when run with JRE 7 however when it is run with JRE 8, following error is being thrown:
java.lang.StackOverflowError
at java.util.Collections.sort(Unknown Source)
at com.mindfusion.common.ExtendedArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.mindfusion.common.ExtendedArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.mindfusion.common.ExtendedArrayList.sort(Unknown Source)
I followed the stack trace to JDiagram decompiled code. Observed that routeAllLinks() calls RouteLinks() on another object (say router) and at one more level deep ExtendedArrayList.sort() which is appeared in error stack trace is called. The "ExtendedArrayList" in JDiagram extends ArrayList and contains a method named "sort()" which has following definition.
public void sort(Comparator<? super T> paramComparator)
{
Collections.sort(this, paramComparator);
}
On Google I found out that JRE 8 has introduced List.sort() and delegates the Collections.sort() calls to collection's (ExtendedArrayList in my case) sort method. And so library ExtendedArrayList.sort() became an override. And it creates an infinite recursion which results in stackoverflow. I could reproduce this issue even with small piece of code as well now.
Also
Our original class which creates JDiagram object, is being loaded at runtime by some other component in our product. We have very little control over the loading of our program.
We have found out that latest version of JDiagram has fixed this issue by replacing sort() with sortJ7() method. However, we cannot upgrade the library at this moment. JDiagram is a licensed API.
ExtendedArrayList is being instantiated by JDiagram internally and so we cannot alter it from our code.
We have tried following solutions which didn't work so far
Java Proxy: Because our code does not call ExtendedArrayList directly
and also 'Diagram' does not have any interface.
Spring AOP: We are
not using spring and also our program is loaded runtime by other
component.
AspectJ: By now, this was apparently a solution. However,
it also didn't work as we are not able to weave our program at
runtime. Not sure if someone could make it work.
Kindly let me know if any point needs elaboration.
Any help is welcome. Thanks.
UPDATE
So far, javassist is the best approach however there JDiagram obfuscation is preventing the solution to work correctly. We have kind of assumed that it is impossible (have to say) to fix considering our release date on our head. We have started process to upgrade library. And meanwhile removed a small feature from our application which was being provided by routeAllLinks() method.. :-(
thanks everyone for your help. I'll be continuing my research on this issue as I found it really intriguing and challenging.. I'll update the post if I could resolve it.. And I'll be giving bounty to #gontard for his javassist approach as I'm continuing my research with it. Thanks.
I have reproduced your problem with a basic example:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ExtendedArrayList<E> extends ArrayList<E> {
#Override
public void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
}
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
ExtendedArrayList<String> arrayList = new ExtendedArrayList<String>();
arrayList.addAll(Arrays.asList("z", "y", "x"));
arrayList.sort(String::compareTo); // -> java.lang.StackOverflowError
}
}
I was able to bypass the java.lang.StackOverflowError by renaming the method using javassist:
import java.util.Arrays;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
public class Main {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.get("ExtendedArrayList");
CtClass[] sortParams = new CtClass[]{ pool.get("java.util.Comparator")};
CtMethod sortMethod = ctClass.getDeclaredMethod("sort", sortParams);
sortMethod.setName("sortV7"); // rename
ctClass.toClass();
ExtendedArrayList<String> arrayList = new ExtendedArrayList<String>();
arrayList.addAll(Arrays.asList("z", "y", "x"));
System.err.println(arrayList); // print [z, y, x]
arrayList.sort(String::compareTo);
System.err.println(arrayList); // print [x, y, z]
}
}
I have not tried with your version of JDiagram because I get only the last (Java 8 compatible) version on their website.
Think about decompiling the library and fixing the issue by yourself. You could use this fixed package as a workaround.
An alternative would be, to place a fixed version of the class in your code. Same package like in the library and same class name of course:
com.mindfusion.common.ExtendedArrayList
Maybe you have to configure the classloader to load your class instead of looking up the faulty class in the library first. Options like "parent first" or simply accessing the class from your code once before calling the library could make the deal.
I see that the loading of your program is not controlled by you.
Perform the following steps:
Include the jar(javassist) of the program that could change the "sort" method name to any other name that could avoid overriding the sorting method
Load the jar's (javassist) main class by reflection class.forName(""); in the beginning of your program's main method
Call the jar's (javassist) method to perform the required changes you need on the methods
This way you could be sure that any jar (javassist)is loaded and is ready to be used.

JavascriptInterface annotation for JELLY_BEAN and below

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(){ ... };
}

Categories

Resources