puniverse / quasar

Fibers, Channels and Actors for the JVM
http://docs.paralleluniverse.co/quasar/
Other
4.56k stars 575 forks source link

[instrumentationTask] ERROR: /home/.../XX.class #293

Open rendaw opened 6 years ago

rendaw commented 6 years ago

When starting a fiber, I get the error Fiber class com.my.Klass$XXFiber has not been instrumented. I got this error using the maven agent snippet in the docs, as well as AOT (couldn't find the maven code to do AOT in the docs, but this is what I'm using:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
    <execution>
        <id>instrument-classes</id>
        <phase>compile</phase>
        <configuration>
            <tasks>
                <property name="ant_classpath" refid="maven.dependency.classpath"/>
                <taskdef name="instrumentationTask"
                         classname="co.paralleluniverse.fibers.instrument.InstrumentationTask"
                         classpath="${ant_classpath}"/>
                <instrumentationTask>
                    <fileset dir="${project.build.directory}/classes/" includes="**/*.class"/>
                </instrumentationTask>
            </tasks>
        </configuration>
        <goals>
            <goal>run</goal>
        </goals>
    </execution>
</executions>
</plugin>

The maven-dependency-plugin is setup correctly (I'm using it for the enforcer plugin, tested thoroughly).

Running mvn package shows a bunch of lines of output like

[instrumentationTask] ERROR: /home/.../XX.class

for all my classes.

Running and compiling Java 9, in Java 9 mode

$ java -version
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

with Quasar 0.7.9 jdk8 classifier.

Some of the fibers themselves are private (static, originally non static) inner classes, but there are instrumented methods in public outer classes as well and I see the same error for them.

The only thing I think I might have missed is META-INF/suspendables but I couldn't find an example of generating that with maven. https://github.com/puniverse/quasar-mvn-archetype appears to support AOT compilation but I don't see an invocation of the scanner or that file in the source.

Edit: I managed to wrangle up an antrun task for scanning suspendables and that fails with this error:

[scanSuspendables] Classpath URLs: [...]
[scanSuspendables] Project URLs: [file:/home/.../project/target/classes/]
Exception thrown during processing of com/my/klass/ZZ.class at file:/home/.../ZZ.class

There's no further output. ZZ is a pojo; no methods, derived from Object, public everything, only primitive fields.

I think it's possible that I have an overnight epiphany, but not feeling it at the moment. Apologies if this is explained somewhere obvious.

rendaw commented 6 years ago

Follow up questions:

  1. What is the jdk8 classifier needed for?
  2. Why is the agent preferred to AOT? Just because it's easier?
  3. Why would one not want to automatically scan for suspendable methods?
  4. Are there any other restrictions for suspendable methods/calls other than a. no invokedynamic and b. must throw those two exceptions (or use the other workarounds)? Are inner/anonymous classes okay? Private? I realize this isn't reflection but just in case.
rendaw commented 6 years ago

Okay, couldn't sleep. I tried it on a dummy project, set the language level to 8.

scanSuspendables almost works:

[scanSuspendables] Classpath URLs: [... all my classfiles ...]
[scanSuspendables] Project URLs: [...]
[scanSuspendables] Scanned external suspendables in 957 ms
[scanSuspendables] Built method graph in 29 ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.224 s
[INFO] Finished at: 2017-10-14T03:50:35+09:00
[INFO] Final Memory: 21M/68M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.3:run (quasar-scan-classes) on project test: An Ant BuildException has occured: java.lang.NullPointerException -> [Help 1]

Disabling that task I get slightly different errors from above:

[INFO] Executing tasks
[instrumentationTask] ERROR: java/lang/Object
[instrumentationTask] ERROR: java/lang/Runnable
...
[instrumentationTask] ERROR: java/lang/Integer
[instrumentationTask] ERROR: java/io/PrintStream
[instrumentationTask] ERROR: java/util/concurrent/ExecutionException
[instrumentationTask] ERROR: java/lang/Integer
[instrumentationTask] ERROR: java/io/PrintStream
[instrumentationTask] ERROR: java/util/concurrent/ExecutionException
[instrumentationTask] ERROR: Unable to instrument class com/my/klass/Test$2
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.821 s
[INFO] Finished at: 2017-10-14T03:52:59+09:00
[INFO] Final Memory: 19M/63M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.3:run (quasar-instrument-classes) on project test: An Ant BuildException has occured: java.lang.NullPointerException -> [Help 1]
rendaw commented 6 years ago

Hitting https://github.com/puniverse/quasar/issues/253 with the agent at language level 7, AOT failed at that level too.

rendaw commented 6 years ago

All above problems solved AFAICT by switching to JDK/JRE 8. It looks like Java 9 is totally a no-go right now?

To clarify a couple of the above questions, maybe this would be useful in the documentation: 2: The agent works with IDEs that may not perform instrumentation when incrementally compiling or doing hot swapping while debugging (ex: Intellij). 3: The suspendable scanner seems to be an optional step. I'm not sure what it's required for. I didn't need it for AOT instrumentation.

circlespainter commented 6 years ago
  1. The jdk8 classifier provides a build of Quasar optimized and with additional API support for JDK8.
  2. Agent and AOT just apply to different use cases. It's a good idea to AOT-instrument your Quasar-aware code (Quasar itself is AOT-instrumented) but AOT won't help you with 3rd-party libraries not aware of Quasar (unless you use your own AOT-instrumented fork that is) and when writing Quasar integrations you might need to instrument something in them (typically, library code that run in fibers and ends up calling your suspendable code).
  3. SuspendablesScanner is a static analysis tool that can help you identify suspendables.
  4. invokedynamic should work just fine. As for restrictions and usage notes for "special" cases you might want to have a look at the docs

AFAIK JDK9 is not really supported at this stage. @pron Is that correct and do you know of any news about that?

Also consider the Quasar user group for questions and discussions.

rendaw commented 6 years ago

Thanks!

I jumped in with a debugger and it seems like (ASM?) is complaining about the bytecode version header in the classfiles. IIRC it's 53 for javac 9 and 52 for javac 8, regardless of targeted version?

I appreciate the answers to the questions. My mistake on 4. 1 I thought might be relevant to the issue in this ticket, but it seems like it isn't. For 2 and 3 I really intended those as bug reports about the documentation since I think it's misleading as it is now. I'd be glad to pick up discussions on them in the user group though, if you think that would be good.

Glad to close the ticket unless you feel more discussion here would be helpful.