How to serialize a Predicate<T> from Nashorn engine in java 8

纵饮孤独 提交于 2019-12-25 06:50:04

问题


How can i serialize a predicate obtained from java ScriptEngine nashorn? or how can i cast jdk.nashorn.javaadapters.java.util.function.Predicate to Serializable?

Here is the case:

I have this class

import java.io.Serializable;
import java.util.function.Predicate;

public class Filter implements Serializable {

    private Predicate<Object> filter;

    public Predicate<Object> getFilter() {
        return filter;
    }

    public void setFilter(Predicate<Object> filter) {
        this.filter = filter;
    }

    public boolean evaluate(int value) {
        return filter.test(value);
    }
}

and

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.function.Predicate;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class TestFilterSer {

    public static void main(String[] args) throws ScriptException {
        Filter f = new Filter();
        //This works
        //f.setFilter(getCastedPred());

        // But I want this to work
        f.setFilter(getScriptEnginePred());

        System.out.println(f.evaluate(6));

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("pred.ser")))) {
            oos.writeObject(f);
        } catch (IOException e) {
            e.printStackTrace();
        } 

        f= null;

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("pred.ser")))) {
            f= (Filter)ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println(f.evaluate(7));
    }

    public static Predicate<Object> getCastedPred() {
        Predicate<Object> isEven = (Predicate<Object> & Serializable)(i) -> (Integer)i%2 == 0;
        return isEven;
    }


    public static Predicate<Object> getScriptEnginePred() throws ScriptException {

        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");

        Predicate<Object> p =  (Predicate<Object> & Serializable)engine.eval(
                    String.format("new java.util.function.Predicate(%s)", "function(i) i%2==0")
                );

        return p;
    }
}

Requirement: To be able to serialize the Predicate obtained from Nashorn engine.

Observation: When I get Predicate from method getCastedPred(). It works because it is java.util.function.Predicate. it does Serialize after casting to Serializable. But when I get the Predicate from the Nashorn engine, Internally it returns me the jdk.nashorn.javaadapters.java.util.function.Predicate this one doesn't Serialize and casting to Serializable doesn't work.

Any idea how can i serialize this type of Predicate?


回答1:


The problem is your API uses Predicate, not AggregateFilter. So the target type for the lambda in

setAggregatePredicate(x -> true)

will be Predicate, not AggregateFilter -- and the compiler won't know to make it serializable. If you change your API to use the more specific functional interface, serializable lambdas will be generated.



来源:https://stackoverflow.com/questions/38243299/how-to-serialize-a-predicatet-from-nashorn-engine-in-java-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!