getFileNames(final File directory) throws IOException {
+ return FileUtils.getFileNames(directory, getIncludes(), getExcludes(),
+ false);
+ }
+
/**
* Get the includes pattern
*
diff --git a/jacoco-maven-plugin/src/org/jacoco/maven/InstrumentMojo.java b/jacoco-maven-plugin/src/org/jacoco/maven/InstrumentMojo.java
new file mode 100644
index 0000000000..0888b7967d
--- /dev/null
+++ b/jacoco-maven-plugin/src/org/jacoco/maven/InstrumentMojo.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.maven;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.jacoco.core.instr.Instrumenter;
+import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * Performs offline instrumentation. Note that after execution of test you must
+ * restore original classes with help of "restore-instrumented-classes" goal.
+ *
+ * Warning: The preferred way for code coverage analysis with
+ * JaCoCo is on-the-fly instrumentation. Offline instrumentation has several
+ * drawbacks and should only be used if a specific scenario explicitly requires
+ * this mode. Please consult documentation about
+ * offline instrumentation before using this mode.
+ *
+ *
+ * @phase process-classes
+ * @goal instrument
+ * @requiresProject true
+ * @since 0.6.2
+ */
+public class InstrumentMojo extends AbstractJacocoMojo {
+
+ @Override
+ public void executeMojo() throws MojoExecutionException,
+ MojoFailureException {
+ final File originalClassesDir = new File(getProject().getBuild()
+ .getDirectory(), "generated-classes/jacoco");
+ originalClassesDir.mkdirs();
+ final File classesDir = new File(getProject().getBuild()
+ .getOutputDirectory());
+ if (!classesDir.isDirectory()) {
+ getLog().info("skip non existing outputDirectory " + classesDir);
+ return;
+ }
+
+ final List fileNames;
+ try {
+ fileNames = new FileFilter(this.getIncludes(),
+ this.getExcludes()).getFileNames(classesDir);
+ } catch (final IOException e1) {
+ throw new MojoExecutionException(
+ "Unable to get list of files to instrument.", e1);
+ }
+
+ final Instrumenter instrumenter = new Instrumenter(
+ new OfflineInstrumentationAccessGenerator());
+ for (final String fileName : fileNames) {
+ if (fileName.endsWith(".class")) {
+ final File source = new File(classesDir, fileName);
+ final File backup = new File(originalClassesDir, fileName);
+ InputStream input = null;
+ OutputStream output = null;
+ try {
+ FileUtils.copyFile(source, backup);
+ input = new FileInputStream(backup);
+ output = new FileOutputStream(source);
+ instrumenter.instrument(input, output);
+ } catch (final IOException e2) {
+ throw new MojoExecutionException(
+ "Unable to instrument file.", e2);
+ } finally {
+ IOUtil.close(input);
+ IOUtil.close(output);
+ }
+ }
+ }
+ }
+
+}
diff --git a/jacoco-maven-plugin/src/org/jacoco/maven/RestoreMojo.java b/jacoco-maven-plugin/src/org/jacoco/maven/RestoreMojo.java
new file mode 100644
index 0000000000..f9e5ecbb98
--- /dev/null
+++ b/jacoco-maven-plugin/src/org/jacoco/maven/RestoreMojo.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.maven;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Restores original classes as they were before offline instrumentation.
+ *
+ * @phase prepare-package
+ * @goal restore-instrumented-classes
+ * @requiresProject true
+ * @since 0.6.2
+ */
+public class RestoreMojo extends AbstractJacocoMojo {
+
+ @Override
+ protected void executeMojo() throws MojoExecutionException,
+ MojoFailureException {
+ final File originalClassesDir = new File(getProject().getBuild()
+ .getDirectory(), "generated-classes/jacoco");
+ final File classesDir = new File(getProject().getBuild()
+ .getOutputDirectory());
+ try {
+ FileUtils.copyDirectoryStructure(originalClassesDir, classesDir);
+ } catch (final IOException e) {
+ throw new MojoFailureException("Unable to restore classes.", e);
+ }
+ }
+
+}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 5fc5c24726..d1926a79f6 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -22,7 +22,7 @@ Trunk Build @qualified.bundle.version@ (@build.date@)
New Features
- - Support for offline instrumentation (GitHub #4).
+ - Support for offline instrumentation (GitHub #4, #64).
- JaCoCo agent exposes runtime API for direct integration with application
under test (GitHub #61).
- Support for parallel test execution: Different agents can now safely write
diff --git a/org.jacoco.doc/docroot/doc/index.html b/org.jacoco.doc/docroot/doc/index.html
index 7250e24980..323ad39ad3 100644
--- a/org.jacoco.doc/docroot/doc/index.html
+++ b/org.jacoco.doc/docroot/doc/index.html
@@ -41,7 +41,8 @@
Using JaCoCo
- Ant Usage Example -
Offline Example
- Maven Plug-in
- - Maven Usage Example
+ - Maven Usage Example -
+ Offline Example
- Java Agent
- Offline Instrumentation
- FAQ
diff --git a/org.jacoco.doc/docroot/doc/maven.html b/org.jacoco.doc/docroot/doc/maven.html
index 2c73adcdfa..0c113116b5 100644
--- a/org.jacoco.doc/docroot/doc/maven.html
+++ b/org.jacoco.doc/docroot/doc/maven.html
@@ -90,6 +90,8 @@ Goals
- prepare-agent
- report
- check
+ - instrument
+ - restore-instrumented-classes
diff --git a/org.jacoco.examples/build/pom-offline.xml b/org.jacoco.examples/build/pom-offline.xml
new file mode 100644
index 0000000000..4a08a5f328
--- /dev/null
+++ b/org.jacoco.examples/build/pom-offline.xml
@@ -0,0 +1,92 @@
+
+
+
+ 4.0.0
+
+ org.jacoco
+ org.jacoco.examples.maven
+ @project.version@
+ jar
+
+ JaCoCo Maven plug-in example with Offline Instrumentation
+ http://www.eclemma.org/jacoco
+
+
+
+ junit
+ junit
+ 4.10
+ test
+
+
+
+ org.jacoco
+ org.jacoco.agent
+ runtime
+ @project.version@
+ test
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ @project.version@
+
+
+
+ instrument
+ restore-instrumented-classes
+
+
+
+ report
+ prepare-package
+
+ report
+
+
+
+ check
+
+ check
+
+
+
+ 100
+ 90
+ 95
+ 85
+ 85
+ 90
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.12.2
+
+
+ target/jacoco.exec
+
+
+
+
+
+
+