deathcap / Junket

an implementation of the Bukkit API for JavaScript using doppio (incomplete)
MIT License
2 stars 0 forks source link

[SamplePlugin] Event registration: Error: Assertion failed: Invalid thread transition: RUNNABLE => ASYNC_WAITING #4

Closed deathcap closed 10 years ago

deathcap commented 10 years ago

After removing the command registration to workaround https://github.com/deathcap/Junket/issues/3 in SamplePlugin, it fails shortly after enabling:

Error: Assertion failed: Invalid thread transition: RUNNABLE => ASYNC_WAITING
    at assert (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/assert.ts:6:11)
    at JVMThread.setStatus (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:630:7)
    at BytecodeStackFrame.scheduleException (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:154:20)
    at JVMThread.throwException (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:830:46)
    at InternalStackFrame.cb (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:859:18)
    at InternalStackFrame.run (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:306:12)
    at JVMThread.run (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:568:31)
    at JVMThread.setStatus (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:652:16)
    at Object._onImmediate (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:393:24)
    at processImmediate [as _immediateCallback] (timers.js:330:15)

as of https://github.com/deathcap/SamplePlugin/commit/0a86c427572d5cfad7c5efb8000cd939fe52cb6e

test plugin: https://dl.dropboxusercontent.com/u/258156216/java/bukkit-sample-plugin-0.5-04.jar

deathcap commented 10 years ago

The invalid thread transition is from doppio in scheduleException() https://github.com/plasma-umass/doppio/blob/natives_refactor/src/threading.ts#L154

            // ASYNC PATH: We'll need to asynchronously resolve these handlers.
            debug(method.full_signature() + " needs to resolve some exception types...");
            var handlerClasses: string[] = [];
            exceptionHandlers.forEach((handler: attributes.ExceptionHandler) => {
              if (handler.catch_type !== "<any>") {
                handlerClasses.push(handler.catch_type);
              }
            });
            thread.setStatus(enums.ThreadStatus.ASYNC_WAITING); // *** <-- here

ASYNC_WAITING is not an ordinary Java thread state http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.State.html - from src/enums.ts ASYNC_WAITING "A thread that is waiting for an asynchronous browser operation to complete.". Why is RUNNABLE => ASYNC_WAITING an invalid transition? validTransitions defined in src/hreading.ts, can only go from RUNNABLE to RUNNING. Trying to resolve Ljava/lang/UnsatisfiedLinkError;.

deathcap commented 10 years ago
        pm.registerEvents(playerListener, this);

../doppio/doppio-dev -Xlog trace -jar target/junket-0.0.1.jar

Ljava/util/EnumMap;::put(Ljava/lang/Enum;Ljava/lang/Object;)Ljava/lang/Object;: Did not catch Ljava/lang/NoSuchMethodError;.
Ljava/util/EnumMap;::put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;: Did not catch Ljava/lang/NoSuchMethodError;.
Lorg/yaml/snakeyaml/constructor/SafeConstructor;::<init>()V: Did not catch Ljava/lang/NoSuchMethodError;.
Lorg/bukkit/plugin/PluginDescriptionFile$1$1;::<init>(Lorg/bukkit/plugin/PluginDescriptionFile$1;)V: Did not catch Ljava/lang/NoSuchMethodError;.
Lorg/bukkit/plugin/PluginDescriptionFile$1;::initialValue()Lorg/yaml/snakeyaml/Yaml;: Did not catch Ljava/lang/NoSuchMethodError;.
Lorg/bukkit/plugin/PluginDescriptionFile$1;::initialValue()Ljava/lang/Object;: Did not catch Ljava/lang/NoSuchMethodError;.
Ljava/lang/ThreadLocal;::setInitialValue()Ljava/lang/Object;: Did not catch Ljava/lang/NoSuchMethodError;.
Ljava/lang/ThreadLocal;::get()Ljava/lang/Object;: Did not catch Ljava/lang/NoSuchMethodError;.
Lorg/bukkit/plugin/PluginDescriptionFile;::<init>(Ljava/io/InputStream;)V: Did not catch Ljava/lang/NoSuchMethodError;.
Lorg/bukkit/plugin/java/JavaPluginLoader;::getPluginDescription(Ljava/io/File;)Lorg/bukkit/plugin/PluginDescriptionFile; needs to resolve some exception types...
Error: Assertion failed: Invalid thread transition: RUNNABLE => ASYNC_WAITING
    at assert (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/assert.ts:6:11)
    at JVMThread.setStatus (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:630:7)
    at BytecodeStackFrame.scheduleException (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:154:20)
    at JVMThread.throwException (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:829:46)
    at InternalStackFrame.cb (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:858:18)
    at InternalStackFrame.run (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:306:12)
    at JVMThread.run (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:568:31)
    at JVMThread.setStatus (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:652:16)
    at Object._onImmediate (/Users/admin/games/voxeljs/doppio/build/dev-cli/src/threading.ts:393:24)
    at processImmediate [as _immediateCallback] (timers.js:330:15)

exception from org.bukkit.plugin.PluginDescriptionFile

     public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException {
        loadMap(asMap(YAML.get().load(stream)));

YAML is a ThreadLocal<YAML>. yaml.load(stream)

Disabling assertions shows the exception it is trying to throw:

Assertion failed: Invalid thread transition: RUNNABLE => ASYNC_WAITING
Exception in thread "main" java.lang.NoSuchMethodError: No such method found in org.yaml.snakeyaml.nodes.NodeId::ordinal()I
    at java.util.EnumMap.put(EnumMap.java:260)
    at java.util.EnumMap.put(EnumMap.java:79)
    at org.yaml.snakeyaml.constructor.SafeConstructor.<init>(SafeConstructor.java:63)
    at org.bukkit.plugin.PluginDescriptionFile$1$1.<init>(PluginDescriptionFile.java:181)
    at org.bukkit.plugin.PluginDescriptionFile$1.initialValue(PluginDescriptionFile.java:181)
    at org.bukkit.plugin.PluginDescriptionFile$1.initialValue(PluginDescriptionFile.java:178)
    at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:160)
    at java.lang.ThreadLocal.get(ThreadLocal.java:150)
    at org.bukkit.plugin.PluginDescriptionFile.<init>(PluginDescriptionFile.java:232)
    at org.bukkit.plugin.java.JavaPluginLoader.getPluginDescription(JavaPluginLoader.java:155)
    at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:133)
    at deathcap.junket.ServerImpl.loadPlugins(ServerImpl.java:71)
    at deathcap.junket.ServerImpl.<init>(ServerImpl.java:46)
    at deathcap.junket.Main.main(Main.java:8)

org.yaml.snakeyaml.constructor:

       this.yamlClassConstructors.put(NodeId.scalar, undefinedConstructor);

NodeId is an enum, or it is supposed to be (hence the ordinal()I method). Reproduces with:

    public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException {
        System.out.println("about to read scalar");
        System.out.println("scalar="+org.yaml.snakeyaml.nodes.NodeId.scalar.ordinal()); // crashes
        loadMap(asMap(YAML.get().load(stream)));
    }

but for some reason, the same org.yaml.snakeyaml.nodes.NodeId.scalar.ordinal() code does not crash in isolation.

deathcap commented 10 years ago

Submitted https://github.com/plasma-umass/doppio/issues/314 and added the allowed transition, but I still have the enum problem:

INFO: Loading plugins...
Exception in thread "main" java.lang.NoSuchMethodError: No such method found in org.yaml.snakeyaml.nodes.NodeId::ordinal()I
    at java.util.EnumMap.put(EnumMap.java:260)
    at java.util.EnumMap.put(EnumMap.java:79)
    at org.yaml.snakeyaml.constructor.SafeConstructor.<init>(SafeConstructor.java:63)
    at org.bukkit.plugin.PluginDescriptionFile$1$1.<init>(PluginDescriptionFile.java:181)
    at org.bukkit.plugin.PluginDescriptionFile$1.initialValue(PluginDescriptionFile.java:181)
    at org.bukkit.plugin.PluginDescriptionFile$1.initialValue(PluginDescriptionFile.java:178)
    at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:160)
    at java.lang.ThreadLocal.get(ThreadLocal.java:150)
    at org.bukkit.plugin.PluginDescriptionFile.<init>(PluginDescriptionFile.java:232)
    at org.bukkit.plugin.java.JavaPluginLoader.getPluginDescription(JavaPluginLoader.java:155)
    at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:133)
    at deathcap.junket.ServerImpl.loadPlugins(ServerImpl.java:71)
    at deathcap.junket.ServerImpl.<init>(ServerImpl.java:46)
    at deathcap.junket.Main.main(Main.java:8)

NodeId extends java.lang.Enum:

tmp $ javap -cp snakeyaml-1.9.jar org.yaml.snakeyaml.nodes.NodeId
Compiled from "NodeId.java"
public final class org.yaml.snakeyaml.nodes.NodeId extends java.lang.Enum<org.yaml.snakeyaml.nodes.NodeId> {
  public static final org.yaml.snakeyaml.nodes.NodeId scalar;
  public static final org.yaml.snakeyaml.nodes.NodeId sequence;
  public static final org.yaml.snakeyaml.nodes.NodeId mapping;
  public static final org.yaml.snakeyaml.nodes.NodeId anchor;
  public static final org.yaml.snakeyaml.nodes.NodeId[] values();
  public static org.yaml.snakeyaml.nodes.NodeId valueOf(java.lang.String);
  static {};
}

I previously added a hack to allow my class to extend java.lang.Enum in https://github.com/deathcap/Junket/commit/328af11fa3df3d3d8c60ddf6a9daf982dbe7a3f8, thought this broken enum could be a consequence, but if I remove the relocation pattern the method is still missing. Maybe the fix https://github.com/plasma-umass/doppio/pull/315 is incomplete - or are these two failures completely unrelated? (except that the latter was masking the former)

adding to main:

    public static void main(String[] args) {
        System.out.println("xxx");
        System.out.println("scalar="+org.yaml.snakeyaml.nodes.NodeId.scalar.ordinal());

+ ../doppio/doppio-dev -jar target/junket-0.0.1.jar
xxx
Exception in thread "main" java.lang.NoSuchMethodError: No such method found in org.yaml.snakeyaml.nodes.NodeId::ordinal()I
    at deathcap.junket.Main.main(Main.java:9)
deathcap commented 10 years ago

Reduced test to a simple project linking to Bukkit and calling:

package deathcap.junket;

import org.bukkit.Server;

public class Main {
    public static void main(String[] args) {
        System.out.println("testing...");
        System.out.println("scalar="+org.yaml.snakeyaml.nodes.NodeId.scalar.ordinal());
    }
}

but.. it only occurs with specific filenames. junket-0.0.1.jar. Copy to any other name (tried many variations), works without incident. Seems that there is some hidden state I'm not aware of.

update: classes are cached in /var/folders/81/3xnrrjrn3hzd1sks0yvxwp1w0000gn/T/doppio_jars - by jar name, so junket-0.0.1 caches java/lang/Enum.class.

deathcap commented 10 years ago
+ java -jar target/junket-0.0.1.jar
Hello
May 17, 2014 10:07:55 PM deathcap.junket.ServerImpl <init>
INFO: ServerImpl starting...
May 17, 2014 10:07:55 PM org.bukkit.Bukkit setServer
INFO: This server is running null version null (Implementing API version null)
May 17, 2014 10:07:55 PM deathcap.junket.ServerImpl loadPlugins
INFO: Loading plugins...
May 17, 2014 10:07:56 PM deathcap.junket.ServerImpl loadPlugins
INFO: Loaded 1 plugins
May 17, 2014 10:07:56 PM deathcap.junket.ServerImpl loadPlugins
INFO: Enabling plugin SamplePlugin v0.5
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] Enabling SamplePlugin v0.5
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] SamplePlugin version 0.5 is enabled!
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] dirt = DIRT, name = DIRT, ordinal=3
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got stone
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got dirt
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got else
May 17, 2014 10:07:56 PM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got null
+ ../doppio/doppio-dev -jar target/junket-0.0.1.jar
Hello
May 18, 2014 5:07:59 AM deathcap.junket.ServerImpl <init>
INFO: ServerImpl starting...
May 18, 2014 5:08:06 AM org.bukkit.Bukkit setServer
INFO: This server is running null version null (Implementing API version null)
May 18, 2014 5:08:07 AM deathcap.junket.ServerImpl loadPlugins
INFO: Loading plugins...
May 18, 2014 5:08:33 AM deathcap.junket.ServerImpl loadPlugins
INFO: Loaded 1 plugins
May 18, 2014 5:08:33 AM deathcap.junket.ServerImpl loadPlugins
INFO: Enabling plugin SamplePlugin v0.5
May 18, 2014 5:08:34 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] Enabling SamplePlugin v0.5
May 18, 2014 5:08:34 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] SamplePlugin version 0.5 is enabled!
May 18, 2014 5:08:34 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] dirt = DIRT, name = DIRT, ordinal=3
May 18, 2014 5:08:36 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got stone
May 18, 2014 5:08:36 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got dirt
May 18, 2014 5:08:36 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got else
May 18, 2014 5:08:36 AM org.bukkit.plugin.PluginLogger log
INFO: [SamplePlugin] got null