Maven Configuration for Quasar

1,287 views
Skip to first unread message

Volkan Yazıcı

unread,
Aug 23, 2014, 7:20:44 AM8/23/14
to quasar-pu...@googlegroups.com
Hi!

I am trying to write a Maven application that employs Quasar. Following the steps detailed in the Getting Started page, I added the following snippets into my pom.xml.

<dependencies>
    <dependency>
        <groupId>co.paralleluniverse</groupId>
        <artifactId>quasar-core</artifactId>
        <version>0.6.0</version>
    </dependency>
    ...
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.5.1</version>
            <executions>
                <execution>
                    <id>getClasspathFilenames</id>
                    <goals>
                        <goal>properties</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        ...
    </plugins>
</build>

The rest of the documentation continues as follows.

Later on, use the property it sets as documented here with the form:

groupId:artifactId:type:[classifier]

like so

<argument>-javaagent:${co.paralleluniverse:quasar-core:jar}</argument>

But I really did not understand what further should I do. I just want the instrumentation to kick in at compile time. Could somebody elaborate the necessary steps to configure the Maven?

Best.

pron

unread,
Aug 23, 2014, 11:44:12 AM8/23/14
to quasar-pu...@googlegroups.com
The instrumentation kicks in at runtime with the Java agent. Here's an example:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.3.2</version>

                <configuration>
                    <mainClass>com.example.helloworld.HelloWorldApplication</mainClass>
                    <workingDirectory>target/classes</workingDirectory>
                    <executable>java</executable>
                    <arguments>
                        <argument>-Xmx1000m</argument>
                        <argument>-javaagent:${co.paralleluniverse:quasar-core:jar:jdk8}</argument>
                        <argument>-classpath</argument>
                        <classpath/>
                        <argument>com.example.helloworld.HelloWorldApplication</argument>
                    </arguments>
                </configuration>
            </plugin>

Volkan Yazıcı

unread,
Aug 23, 2014, 11:53:43 AM8/23/14
to quasar-pu...@googlegroups.com
Isn't it possible to make JavaAgent perform the instrumentation at compile time?
I see there is an Ant task for this purpose, but I don't know its Maven equivalent.

pron

unread,
Aug 23, 2014, 12:00:57 PM8/23/14
to quasar-pu...@googlegroups.com
Yes, but you don't use the agent -- only the ant task. I'm no Maven expert, but I think you can run ant tasks from Maven (also, here).

Volkan Yazıcı

unread,
Aug 25, 2014, 10:04:07 AM8/25/14
to quasar-pu...@googlegroups.com
Good news everyone! I have just finished writing quasar-maven-plugin -- this is my first Maven plugin, so be gentle with the comments, please. I tried to follow the procedures employed in c.p.f.instrument.InstrumentationTask. The problem is c.p.f.instrument.QuasarInstrumentor cannot locate the class files passed by the plugin.

Here is the gist:
  1. I tried to copy the exact steps followed by c.p.f.i.InstrumentationTask.
  2. InstrumentationTask uses package internal functions, which I do not have access to.
  3. I copied these functions as best as I could -- see c.g.v.QuasarWrapper.
  4. When I enable check+verbose+debug in the used QuasarInstrumentor instance, I observe the following errors in the Maven console from QuasarInstrumentor#checkClass(File) calls:

    [INFO] Instrumenting Quasar classes...
    [INFO] Reading class: java/lang/Object
    [INFO] Reading class: com/github/vy/fibertest/FiberFactory
    [INFO] Class not found: com/github/vy/fibertest/FiberFactory
    [INFO] Reading class: com/github/vy/fibertest/FiberFactory
    [INFO] Class not found: com/github/vy/fibertest/FiberFactory
    ...
In order to reproduce the problem, you first need to install the quasar-maven-plugin to your local Maven repository as follows.

$ cd quasar-maven-plugin
$ mvn clean install
$ mv install:install-file \
    -Dfile=target/quasar-maven-plugin-1.0-SNAPSHOT.jar \
    -DgroupId=com.github.vy \
    -DartifactId=quasar-maven-plugin \
    -Dversion=1.0-SNAPSHOT \
    -Dpackaging=maven-plugin

Next, create a new Maven project that uses quasar-maven-plugin.

<build>
    <plugins>
        <plugin>
            <groupId>com.github.vy</groupId>
            <artifactId>quasar-maven-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
            <configuration>
                <check>true</check>
                <debug>true</debug>
                <verbose>true</verbose>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>quasar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        ...
    </plugins>
</build>

And build the project via "mvn clean install".

I will be appreciated if somebody could shed some light on the "class not found" errors. If we can get this fixed, we will be able to use Quasar with a simple Maven plugin configuration.

Best.

pron

unread,
Aug 25, 2014, 5:01:25 PM8/25/14
to quasar-pu...@googlegroups.com
Hi Volkan. Nice work! I'll take a look at this in the coming days. 

Eric Myhre

unread,
Aug 26, 2014, 1:26:08 PM8/26/14
to quasar-pu...@googlegroups.com
I recently noticed that the 0.6.0 version of the instrumentor task looks at its own classloader during some parts of the process. (I'm thinking this is probably a bug/oversight -- when using the agent at runtime, that classloader probably has all the relevant references, but if say I'm setting it up to do AOT using the ant task, and I try to isolate the classpath I send to the taskdef to just what quasar needs, I run into a hard time with class not found warnings like this.) I'm not sure if that's your issue, but it might be related.


On 08/25/2014 04:01 PM, pron wrote:
> Hi Volkan. Nice work! I'll take a look at this in the coming days.
>
> On Monday, August 25, 2014 5:04:07 PM UTC+3, Volkan Yazıcı wrote:
>>
>> Good news everyone! I have just finished writing quasar-maven-plugin
>> <https://github.com/vy/quasar-maven-plugin> -- this is my first Maven
>> plugin, so be gentle with the comments, please. I tried to follow the
>> procedures employed in *c.p.f.instrument.InstrumentationTask*
>> <https://github.com/puniverse/quasar/blob/master/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/InstrumentationTask.java>.
>> The problem is *c.p.f.instrument.QuasarInstrumentor*
>> <https://github.com/puniverse/quasar/blob/master/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/QuasarInstrumentor.java>
>> cannot locate the class files passed by the plugin.
>>
>> Here is the gist:
>>
>> 1. I tried to copy the exact steps followed by
>> *c.p.f.i.InstrumentationTask*.
>> 2. *InstrumentationTask* uses package internal functions, which I do
>> not have access to.
>> 3. I copied these functions as best as I could -- see
>> *c.g.v.QuasarWrapper*
>> <https://github.com/vy/quasar-maven-plugin/blob/master/src/main/java/com/github/vy/QuasarWrapper.java>
>> .
>> 4. When I enable check+verbose+debug in the used *QuasarInstrumentor*
>> instance, I observe the following errors in the Maven console from
>> *QuasarInstrumentor#checkClass(File)* calls:
>>> <http://maven.apache.org/plugins/maven-antrun-plugin/> (also, here
>>> <http://stackoverflow.com/questions/3504000/run-ant-task-from-maven>).
>>>>>> <http://docs.paralleluniverse.co/quasar/> page, I added the following
>>>>>> snippets into my *pom.xml*.

pron

unread,
Aug 26, 2014, 2:54:28 PM8/26/14
to quasar-pu...@googlegroups.com
Hi Eric.
Can you point me out to what you think may be an oversight (as it might well be)?

Eric Myhre

unread,
Aug 26, 2014, 4:06:35 PM8/26/14
to quasar-pu...@googlegroups.com
Ach, I meant to finish double checking myself before I filed any bugs, so this might be a little rough on the edges, but here's what I can recall from the last time I had it open:

- InstrumentationTask (the entrypoint from ant) picks up its current contextual classloader around line 114, and hands that to QuasarInstrumentor
- that classloader reference bounces down to the MethodDatabase class
- the MethodDatabase.checkClass method is using it on line 357
- shortly thereafter are the "Class not found" strings

I think that using `getClass().getClassLoader()` from the ant task means that if my output paths for the javac of my own stuff isn't on the classpath I hand to the taskdef for the instrumentor then it's not going to be visible, and I'm even less sure but I think that might additionally cause issues when the instrumentor tries to lookup symbols from the other things my code depended on at compile time.

I *think* the first of the two branches that can result in that string is the one that's failing/null, but I haven't rebuilt quasar with more debugging stuff in order to find out, and I have to admit I don't 100% understand the wizardry in action there.

I don't have a fully worked alternative to suggest (HTH nonetheless), but it seems like maybe the ant task needs a different classloader that looks at paths specified separately from its own classpath, and while I haven't looked at the maven plugin code in detail, it might benefit from the same split.

pron

unread,
Aug 26, 2014, 4:58:24 PM8/26/14
to quasar-pu...@googlegroups.com
You may be right, and if so, that's an easy fix (we build a URLClassLoader based on the Ant FileSets). If you can provide an example of a configuration that results in such an error, it would be really helpful (just so that we know the problem is really fixed).

pron

unread,
Sep 2, 2014, 9:06:16 AM9/2/14
to quasar-pu...@googlegroups.com
I’ve made the necessary QuasarInsrumentor methods public so you wouldn’t have to copy over Quasar code.
I’ll soon start looking into the issue you and Eric have run into.

pron

unread,
Sep 21, 2014, 2:22:40 PM9/21/14
to quasar-pu...@googlegroups.com

Eric, can you provide an example? I’d like to fix this issue.

pron

unread,
Sep 21, 2014, 3:00:25 PM9/21/14
to quasar-pu...@googlegroups.com
Volkan, can you give an example of your setup and class not found errors?

Volkan YAZICI

unread,
Sep 23, 2014, 1:31:57 PM9/23/14
to pron, quasar-pu...@googlegroups.com
Hey Ron!

Actually, I had shared the necessary steps to reproduce the problem (along with some "class not found" messages) up in the thread. (See https://groups.google.com/d/msg/quasar-pulsar-user/MwgjqqBwN3o/PSBa6d-ZyW4J)

Best.

--
You received this message because you are subscribed to a topic in the Google Groups "quasar-pulsar-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/quasar-pulsar-user/MwgjqqBwN3o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to quasar-pulsar-u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

pron

unread,
Oct 5, 2014, 11:58:37 AM10/5/14
to quasar-pu...@googlegroups.com, r...@paralleluniverse.co
I’ve submitted a pull request to your plugin that should address this. First, I’ve exposed some internal Quasar classes as public, so now your plugin can be much simpler, but that’s not the core of the issue. That is probably the result of how you’ve defined the instrumentor’s class-loader. Can you give it a try with my changes?


On Tuesday, September 23, 2014 8:31:57 PM UTC+3, Volkan Yazıcı wrote:
Hey Ron!

Actually, I had shared the necessary steps to reproduce the problem (along with some "class not found” t messages) up in the thread. (See https://groups.google.com/d/msg/quasar-pulsar-user/MwgjqqBwN3o/PSBa6d-ZyW4J)

Best.

To unsubscribe from this group and all its topics, send an email to quasar-pulsar-user+unsub...@googlegroups.com.

Volkan YAZICI

unread,
Oct 10, 2014, 12:28:20 PM10/10/14
to pron, quasar-pu...@googlegroups.com
Hi Ron,

Sorry for the late reply. I wasted days to introduce unit tests for quasar-maven-plugin, but it turned out into a Maven torture. The problem was to make the instrumentation plugin to instrument its test classes prior to running tests. Finally, I gave up on unit tests and created a separate repository that tests the plugin: quasar-maven-plugin-test. Long story short: It works!

Here are the steps to reproduce the tests:

$ cd quasar-maven-plugin
$ mvn clean install install:install-file \
-Dfile=target/quasar-maven-plugin-1.0-SNAPSHOT.jar \
-DgroupId=com.github.vy \
-DartifactId=quasar-maven-plugin \
-Dversion=1.0-SNAPSHOT \
-Dpackaging=maven-plugin

$ cd quasar-maven-plugin-test
$ mvn clean install assembly:single
...
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ quasar-maven-plugin-test ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/vy/java/quasar-maven-plugin-test/target/classes
[INFO]
[INFO] --- quasar-maven-plugin:1.0-SNAPSHOT:instrument (default) @ quasar-maven-plugin-test ---
[INFO] Instrumenting Quasar classes...
[INFO] Reading class: java/lang/Object
[INFO] Reading class: co/paralleluniverse/strands/SuspendableCallable
[INFO] Reading class: java/io/Serializable
[INFO] Found class: /home/vy/java/quasar-maven-plugin-test/target/classes/com/github/vy/maven/plugins/quasar/test/FiberTest$1.class
[INFO] Instrumenting 1 classes...
[INFO] TRANSFORM: com/github/vy/maven/plugins/quasar/test/FiberTest$1
[INFO] Method com/github/vy/maven/plugins/quasar/test/FiberTest$1#<init> suspendable: NON_SUSPENDABLE (markedSuspendable: NON_SUSPENDABLE setSuspendable: NON_SUSPENDABLE)
[INFO] Method com/github/vy/maven/plugins/quasar/test/FiberTest$1#run suspendable: SUSPENDABLE (markedSuspendable: SUSPENDABLE setSuspendable: SUSPENDABLE)
[INFO] Method com/github/vy/maven/plugins/quasar/test/FiberTest$1#run suspendable: SUSPENDABLE (markedSuspendable: SUSPENDABLE setSuspendable: SUSPENDABLE)
[INFO] About to instrument method com/github/vy/maven/plugins/quasar/test/FiberTest$1#run()Ljava/lang/Integer;
[INFO] Reading class: co/paralleluniverse/strands/Strand
[INFO] Instrumenting method com/github/vy/maven/plugins/quasar/test/FiberTest$1#run()Ljava/lang/Integer;
[INFO] About to instrument method com/github/vy/maven/plugins/quasar/test/FiberTest$1#run()Ljava/lang/Object;
[INFO] Instrumenting method com/github/vy/maven/plugins/quasar/test/FiberTest$1#run()Ljava/lang/Object;
...
$ java \
-cp target/quasar-maven-plugin-test-1.0-SNAPSHOT-jar-with-dependencies.jar \
com.github.vy.maven.plugins.quasar.test.FiberTest
QUASAR WARNING: Quasar Java Agent isn't running. If you're using another instrumentation method you can ignore this message; otherwise, please refer to the Getting Started section in the Quasar documentation.
$ _      # No output means JUnit did not bark.

Per see, it works without a problem -- right? That being said, it would be better if there will be a way to turn off the QUASAR WARNING line. Additionally, replacing INFO messages with DEBUG/TRACE would look more convenient. I suppose that is it. Ron? What's next?

Best.


To unsubscribe from this group and all its topics, send an email to quasar-pulsar-u...@googlegroups.com.

pron

unread,
Oct 10, 2014, 12:32:17 PM10/10/14
to quasar-pu...@googlegroups.com, r...@paralleluniverse.co
Great!
There is a way to turn off the warning: -Dco.paralleluniverse.fibers.disableAgentWarning

What’s next? Use Quasar to write a cool scalable application !
To unsubscribe from this group and all its topics, send an email to quasar-pulsar-user+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages