Skip to content

Commit

Permalink
Fix Maven plugin to correctly handle test-only dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
vsilaev committed Feb 10, 2022
1 parent 02d7253 commit 1ab3286
Show file tree
Hide file tree
Showing 18 changed files with 67 additions and 72 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![Maven Central](https://img.shields.io/maven-central/v/net.tascalate.javaflow/net.tascalate.javaflow.parent.svg)](https://search.maven.org/artifact/net.tascalate.javaflow/net.tascalate.javaflow.parent/2.7.0/pom) [![GitHub release](https://img.shields.io/github/release/vsilaev/tascalate-javaflow.svg)](https://github.com/vsilaev/tascalate-javaflow/releases/tag/2.7.0) [![license](https://img.shields.io/github/license/vsilaev/tascalate-javaflow.svg)](http://www.apache.org/licenses/LICENSE-2.0.txt)
[![Maven Central](https://img.shields.io/maven-central/v/net.tascalate.javaflow/net.tascalate.javaflow.parent.svg)](https://search.maven.org/artifact/net.tascalate.javaflow/net.tascalate.javaflow.parent/2.7.1/pom) [![GitHub release](https://img.shields.io/github/release/vsilaev/tascalate-javaflow.svg)](https://github.com/vsilaev/tascalate-javaflow/releases/tag/2.7.1) [![license](https://img.shields.io/github/license/vsilaev/tascalate-javaflow.svg)](http://www.apache.org/licenses/LICENSE-2.0.txt)

# IMPORTANT NOTICE FOR RELEASE 2.7.0!!!
# IMPORTANT NOTICE FOR RELEASE 2.7.1!!!
- Agents & Tools projects were refactored to follow consisntent naming of classes and to avoid package name clashes
- Separate provider was extracted from `CdiProxy` to allow reuse in mutliple scenarious (not only in Java Agent)
- `net.tascalate.javaflow.provider.asm[VERSION]` artifacts are deprecated now and scheduled for removal in next release
Expand Down Expand Up @@ -34,7 +34,7 @@ You have to add the following configuration to enable build-time instrumentation
<dependency>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.api</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
</dependency>
<!-- Add-on for Java 8 and above -->
<dependency>
Expand All @@ -59,7 +59,7 @@ You have to add the following configuration to enable build-time instrumentation
<plugin>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.tools.maven</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<executions>
<execution>
<phase>process-classes</phase>
Expand All @@ -72,7 +72,7 @@ You have to add the following configuration to enable build-time instrumentation
</plugins>
</build>
```
Note that if you are using continuations with Java 1.8 lambdas then you need to add [Tascalate JavaFlow instrumentation agent](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.0/javaflow.instrument-continuations.jar) at run-time as command-line option, while lambda-related classes are generated by JVM on the fly and there is no other way to instrument them. If this is not an option, then you can de-sugar all lambdas with [RetroLambda](https://github.com/luontola/retrolambda) Maven plugin at build-time (RetroLambda output is supported by Tascalate JavaFlow 2.3.2 or higher).
Note that if you are using continuations with Java 1.8 lambdas then you need to add [Tascalate JavaFlow instrumentation agent](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.1/javaflow.instrument-continuations.jar) at run-time as command-line option, while lambda-related classes are generated by JVM on the fly and there is no other way to instrument them. If this is not an option, then you can de-sugar all lambdas with [RetroLambda](https://github.com/luontola/retrolambda) Maven plugin at build-time (RetroLambda output is supported by Tascalate JavaFlow 2.3.2 or higher).

Please refer to [pom.xml](https://github.com/vsilaev/tascalate-javaflow-examples/blob/master/net.tascalate.javaflow.examples.common/pom.xml) in examples project for typical Maven configuration

Expand Down Expand Up @@ -101,7 +101,7 @@ It's possibe to instrument compiled Java classes as below:
You may download a complete [examples project setup](https://github.com/vsilaev/tascalate-javaflow-examples/releases/download/1.0.10/tascalate-javaflow-ant-project-setup1.zip) from [the latest release](https://github.com/vsilaev/tascalate-javaflow-examples/releases/tag/1.0.10) for complete configuration template. Please pay attention to <code>ant-lib</code> folder with Ant TaskDef and <code>lib</code> folders with compile-/runtime-dependencies.

# Java Instrumentation Agent (Runt-time Instrumentation)
As an alternative to compile-time bytecode instrumentation, you MAY use [Tascalate JavaFlow Instrumentation Agent](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.0/javaflow.instrument-continuations.jar) from [the latest release](https://github.com/vsilaev/tascalate-javaflow/releases/tag/2.7.0) to enable continuations support at class-loading time. Please note, that if you are using Java 8 and creating continuable lambda functions (either anonymous or/and as method references), and you don't replace them with tools like [RetroLambda](https://github.com/luontola/retrolambda) as mentioned above, then you SHOULD use this instrumentation agent always: as long as Java run-time generates implementation of functional interfaces on the fly there is no other option to instrument them. To enable Tascalate JavaFlow Instrumentation Agent please add the following arguments to Java command line:
As an alternative to compile-time bytecode instrumentation, you MAY use [Tascalate JavaFlow Instrumentation Agent](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.1/javaflow.instrument-continuations.jar) from [the latest release](https://github.com/vsilaev/tascalate-javaflow/releases/tag/2.7.1) to enable continuations support at class-loading time. Please note, that if you are using Java 8 and creating continuable lambda functions (either anonymous or/and as method references), and you don't replace them with tools like [RetroLambda](https://github.com/luontola/retrolambda) as mentioned above, then you SHOULD use this instrumentation agent always: as long as Java run-time generates implementation of functional interfaces on the fly there is no other option to instrument them. To enable Tascalate JavaFlow Instrumentation Agent please add the following arguments to Java command line:
```bash
java -javaagent:<path-to-jar>/javaflow.instrument-continuations.jar <rest-of arguments>
```
Expand All @@ -110,15 +110,15 @@ The agent JAR file includes all necessary dependencies and requires no additiona
Another useful application of the instrumentation agent is to apply it for debugging code within your IDE of choice. Just specify the "-javaagent" option listed above in your IDE debug/run configuration and you will be able to perform quick "debug-fix" loops without executing full project rebuild.

# Command-line tools
It's possible to use a stand-alone command-line utility [JavaFlowRewriteJar.jar](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.0/JavaFlowRewriteJar.jar) to instrument JAR archives containing continuable classes. Please use the following command:
It's possible to use a stand-alone command-line utility [JavaFlowRewriteJar.jar](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.1/JavaFlowRewriteJar.jar) to instrument JAR archives containing continuable classes. Please use the following command:

```bash
java -jar JavaFlowRewriteJar.jar src1.jar dst1.jar src2.jar dst2.jar...
```
Note, that the source and the destination should be different files.

# CDI Support
To work correctly in CDI environment continuable methods should be advised only by continuation-aware CDI proxies (interceptors, scope proxies, etc). Obviously, generation of these proxies is out of our control. Plus, major CDI containers (JBoss Weld and Apache OpenWebBeans) generates such proxies dynamically at run-time. Therefore if you plan to use Tascalate JavaFlow continuations with managed beans' methods then it's necessary to instrument CDI-specific proxies with [javaflow.instrument-proxies.jar](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.0/javaflow.instrument-proxies.jar) Java Agent:
To work correctly in CDI environment continuable methods should be advised only by continuation-aware CDI proxies (interceptors, scope proxies, etc). Obviously, generation of these proxies is out of our control. Plus, major CDI containers (JBoss Weld and Apache OpenWebBeans) generates such proxies dynamically at run-time. Therefore if you plan to use Tascalate JavaFlow continuations with managed beans' methods then it's necessary to instrument CDI-specific proxies with [javaflow.instrument-proxies.jar](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.1/javaflow.instrument-proxies.jar) Java Agent:
```bash
java -javaagent:<path-to-jar>/javaflow.instrument-proxies.jar <rest-of arguments>
```
Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.agent.common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.agent.core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.agent.proxy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.providers.asm3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.providers.asm4/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.providers.asm5/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.providers.asmx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.providers.core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.providers.proxy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.spi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.tools.ant/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.tools.jar/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.tools.maven/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@
import static java.lang.Thread.currentThread;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
Expand All @@ -53,7 +55,7 @@
* </pre>
*
*/
@Mojo(name = "javaflow-enhance", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
@Mojo(name = "javaflow-enhance", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.TEST /* ALL DEPENDENCIES */)
public class ContinuableClassesInstrumentationMojo extends AbstractMojo {

@Parameter(defaultValue = "${project}", property = "javaflow.enhancer.project", required = true, readonly = true)
Expand Down Expand Up @@ -85,33 +87,59 @@ public class ContinuableClassesInstrumentationMojo extends AbstractMojo {
@Parameter(property = "javaflow.enhancer.testBuildDir", required = false)
private String testBuildDir;

@Component
private MojoExecution execution;

public void execute() throws MojoExecutionException {
final Log log = getLog();
if (skip) {
log.info("Skipping executing.");
return;
}

ClassLoader originalContextClassLoader = currentThread().getContextClassLoader();

try {
List<URL> classPath = new ArrayList<URL>();

for (String runtimeResource : project.getRuntimeClasspathElements()) {
classPath.add(resolveUrl(new File(runtimeResource)));
}

File inputDirectory = buildDir == null
File mainInputDirectory = buildDir == null
? new File(project.getBuild().getOutputDirectory())
: computeDir(buildDir);

if (mainInputDirectory.exists()) {
// Use runtime instead of compile - runtime contains non less than compile
transformFiles(mainInputDirectory, project.getRuntimeClasspathElements());
} else {
log.warn("No main build output directory available, skipping enhancing main classes");
}

classPath.add(resolveUrl(inputDirectory));
if (includeTestClasses) {
File testInputDirectory = testBuildDir == null
? new File(project.getBuild().getTestOutputDirectory())
: computeDir(testBuildDir);

loadAdditionalClassPath(classPath);
if (testInputDirectory.exists()) {
transformFiles(testInputDirectory, project.getTestClasspathElements());
} else if ("process-test-classes".equals(execution.getLifecyclePhase())) {
log.warn("No test build output directory available, skipping enhancing test classes");
}
}
} catch (Exception e) {
getLog().error(e.getMessage(), e);
throw new MojoExecutionException(e.getMessage(), e);
}
}

private void transformFiles(File inputDirectory, List<String> classPathEntries) throws IOException {
final Log log = getLog();
ClassLoader originalContextClassLoader = currentThread().getContextClassLoader();
try {
List<URL> classPath = new ArrayList<URL>();
for (String classPathEntry : classPathEntries) {
classPath.add(resolveUrl(new File(classPathEntry)));
}
classPath.add(resolveUrl(inputDirectory));

ResourceTransformer dirTransformer = RewritingUtils.createTransformer(
classPath.toArray(new URL[] {})
);

try {
long now = System.currentTimeMillis();

Expand All @@ -124,47 +152,14 @@ public void execute() throws MojoExecutionException {
}
}
}

if (includeTestClasses) {
File testInputDirectory = testBuildDir == null
? new File(project.getBuild().getTestOutputDirectory())
: computeDir(testBuildDir);

if (testInputDirectory.exists()) {
for (File source : RecursiveFilesIterator.scanClassFiles(testInputDirectory)) {
if (source.lastModified() <= now) {
log.debug("Applying continuations support: " + source);
boolean rewritten = RewritingUtils.rewriteClassFile(source, dirTransformer, source);
if (rewritten) {
log.info("Rewritten continuation-enabled class file: " + source);
}

}
}
}
}
} finally {
dirTransformer.release();
}
} catch (Exception e) {
getLog().error(e.getMessage(), e);
throw new MojoExecutionException(e.getMessage(), e);

} finally {
currentThread().setContextClassLoader(originalContextClassLoader);
}
}

private void loadAdditionalClassPath(List<URL> classPath) {
if (classPath.isEmpty()) {
return;
}
ClassLoader contextClassLoader = currentThread().getContextClassLoader();

URLClassLoader pluginClassLoader = URLClassLoader.newInstance(
classPath.toArray(new URL[classPath.size()]), contextClassLoader
);

currentThread().setContextClassLoader(pluginClassLoader);

}

private File computeDir(String dir) {
Expand Down
2 changes: 1 addition & 1 deletion net.tascalate.javaflow.tools.runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>net.tascalate.javaflow</groupId>
<artifactId>net.tascalate.javaflow.parent</artifactId>
<version>2.7.0</version>
<version>2.7.1</version>
<packaging>pom</packaging>

<name>Tascalate JavFlow</name>
Expand Down

0 comments on commit 1ab3286

Please sign in to comment.