mozilla / rhino

Rhino is an open-source implementation of JavaScript written entirely in Java
https://rhino.github.io
Other
4.17k stars 846 forks source link

Defining class occurred ClassCastException #797

Closed Coalery closed 3 years ago

Coalery commented 3 years ago
    private void initializeScript() {
        rhino = org.mozilla.javascript.Context.enter();
        rhino.setOptimizationLevel(-1);

        try {
            scope = rhino.initStandardObjects();
            rhino.setLanguageVersion(Context.VERSION_1_8);

            ScriptableObject.defineClass(scope, BlacklistApi.class);

            Scriptable blacklist = rhino.newObject(scope, "BlacklistApi");
            scope.put("blacklist", scope, blacklist);
            blacklistApi = (BlacklistApi) blacklist;

            rhino.evaluateString(scope, code, "JavaScript", 1, null);
            callScriptMethod("onStart", new Object[] {});
        } catch(Exception e) {
            log(e.toString());
        } finally {
//            org.mozilla.javascript.Context.exit();
        }
    }

This code is run well.

But, If I add classes, It occurred exception.

    private void initializeScript() {
        rhino = org.mozilla.javascript.Context.enter();
        rhino.setOptimizationLevel(-1);

        try {
            scope = rhino.initStandardObjects();
            rhino.setLanguageVersion(Context.VERSION_1_8);

            ScriptableObject.defineClass(scope, BlacklistApi.class);
            ScriptableObject.defineClass(scope, RandomApi.class);
            ScriptableObject.defineClass(scope, RandomItem.class);

            Scriptable blacklist = rhino.newObject(scope, "BlacklistApi");
            scope.put("blacklist", scope, blacklist);
            blacklistApi = (BlacklistApi) blacklist;

            Scriptable random = rhino.newObject(scope, "RandomApi");

            rhino.evaluateString(scope, code, "JavaScript", 1, null);
            callScriptMethod("onStart", new Object[] {});
        } catch(Exception e) {
            log(e.toString());
        } finally {
//            org.mozilla.javascript.Context.exit();
        }
    }

This above code occurred this exception:

2020-12-08 12:03:29.613 12964-13921/coalery.twitchbotcreator W/System.err: java.lang.ClassCastException: org.mozilla.javascript.UniqueTag cannot be cast to org.mozilla.javascript.Function
2020-12-08 12:03:29.614 12964-13921/coalery.twitchbotcreator W/System.err:     at coalery.twitchbotcreator.TwitchBot.callScriptMethod(TwitchBot.java:150)
2020-12-08 12:03:29.614 12964-13921/coalery.twitchbotcreator W/System.err:     at coalery.twitchbotcreator.TwitchBot.handleLine(TwitchBot.java:105)
2020-12-08 12:03:29.614 12964-13921/coalery.twitchbotcreator W/System.err:     at org.jibble.pircbot.InputThread.run(InputThread.java:92)

TwitchBot.java:150 is this:

    private Object callScriptMethod(String name, Object[] args) {
        try {
            Log.i("TESTTESTTEST", "aejfopawe");
            Function func = (Function)scope.get(name, scope); // Here!
            Log.i("TESTTESTTEST", func.toString());
            return func.call(rhino, scope, scope, args);
        } catch(ClassCastException cast) {
            cast.printStackTrace();
        } catch(Exception e) {
            Log.d("TwitchBotCreator", "Failed to call function - " + name);
        }
        return null;
    }

And TwitchBot.java:105 is this:

    @Override
    protected void handleLine(String line) {
        Log.d("Received", line);

        String[] split = line.split(" ");

        if(!split[2].equals("PRIVMSG")) return;

        Log.i("TESTTESTTEST0", "1");

        HashMap<String, String> map = new HashMap<>();
        for(String kv : split[0].split(";")) {
            String[] kv_split = kv.split("=");
            if(kv_split.length == 1) {
                map.put(kv_split[0], null);
            } else {
                map.put(kv_split[0], kv_split[1]);
            }
        }

        Log.i("TESTTESTTEST0", "2");

        ArrayList<String> badges = new ArrayList<>();
        String rawBadges = map.get("badges");
        if(rawBadges != null) {
            String[] badge_split = rawBadges.split(",");
            for(String badge : badge_split)
                badges.add(badge.split("/")[0]);
        }

        Log.i("TESTTESTTEST0", "3");

        StringBuilder sb = new StringBuilder();
        for(int i=4; i<split.length; i++) {
            if(sb.length() > 0) sb.append(" ");
            sb.append(split[i]);
        }

        Log.i("TESTTESTTEST0", "4");

        Scriptable badge_array = rhino.newArray(scope, badges.toArray());
        String sender_id = split[1].split("!")[0].substring(1);
        String sender_nickname = map.get("display-name");
        String message = sb.toString();

        Log.i("TESTTESTTEST0", "5");

        if(message.charAt(0) == ':')
            message = message.substring(1);

        Log.i("TESTTESTTEST2", "1");
//        Log.i("TESTTESTTEST1", blacklistApi.toString());
        Log.i("TESTTESTTEST2", "2");

        if(blacklistApi != null && blacklistApi.contains(sender_id)) return;

        Log.i("TESTTESTTEST1", "2");

        Object obj = callScriptMethod("onMessageReceived", new Object[] {channel, badge_array, sender_id, sender_nickname, message}); // Here!@@@@@@@@@@@@@@

        Log.i("TESTTESTTEST1", "3");

        if(obj == null) return;

        Log.i("TESTTESTTEST1", "4");

        if(obj instanceof Undefined) return;

        Log.i("TESTTESTTEST1", "5");

        sendMessage(channel, obj.toString());
    }

How can I resolve it?

p-bakker commented 3 years ago

Am sorry, but I don't think we can do much with this issue in its current form: it's missing a straight-forward reproducible sample, instead containing a lot of code snippets that are both not executable and contain a lot of code that is probably not relevant for the exception you're getting.

All I can offer is that you're trying to get a value by name from a certain scope, but that returns undefined. And they you try to cast that undefined value to a function, which correctly gives you a ClassCastException, as undefined isn't a function.

Am closing this case, feel free to reopen with a reproducible sample if you're still experiencing this problem