You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@batchee.apache.org by rm...@apache.org on 2014/01/05 21:12:00 UTC
git commit: BATCHEE-12 adding bar mvn goal and support in cli
Updated Branches:
refs/heads/master 0dd9d2c4d -> 012278dd7
BATCHEE-12 adding bar mvn goal and support in cli
Project: http://git-wip-us.apache.org/repos/asf/incubator-batchee/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-batchee/commit/012278dd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-batchee/tree/012278dd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-batchee/diff/012278dd
Branch: refs/heads/master
Commit: 012278dd7fdcc82b79f8dad6e9ffae6e73b41e4d
Parents: 0dd9d2c
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Sun Jan 5 21:11:47 2014 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Sun Jan 5 21:11:47 2014 +0100
----------------------------------------------------------------------
tools/cli/pom.xml | 50 ++++-
.../classloader/ChildFirstURLClassLoader.java | 114 +++++++++++
.../batchee/cli/command/JobOperatorCommand.java | 96 ++++++++--
.../java/org/apache/batchee/cli/zip/Zips.java | 92 +++++++++
tools/maven-plugin/pom.xml | 138 +++++++------
.../org/apache/batchee/tools/maven/BarMojo.java | 192 +++++++++++++++++++
.../resources/META-INF/plexus/components.xml | 45 +++++
7 files changed, 652 insertions(+), 75 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/cli/pom.xml
----------------------------------------------------------------------
diff --git a/tools/cli/pom.xml b/tools/cli/pom.xml
index 098d20d..4f1f592 100644
--- a/tools/cli/pom.xml
+++ b/tools/cli/pom.xml
@@ -27,7 +27,7 @@
</parent>
<artifactId>batchee-cli</artifactId>
- <name>BatchEE :: CLI</name>
+ <name>BatchEE :: Tools :: CLI</name>
<dependencies>
<dependency>
@@ -54,12 +54,23 @@
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
<version>0.6</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
<!-- for lifecycles -->
<dependency>
@@ -92,4 +103,41 @@
<version>1.4.0</version>
</dependency>
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <createDependencyReducedPom>false</createDependencyReducedPom>
+ <artifactSet>
+ <excludes>
+ <exclude>org.springframework:*</exclude>
+ <exclude>org.apache.geronimo.specs:geronimo-ejb_3.1_spec</exclude>
+ <exclude>org.apache.deltaspike.cdictrl:deltaspike-cdictrl-api</exclude>
+ <exclude>org.testng:*</exclude>
+ <exclude>org.junit:*</exclude>
+ <exclude>org.hamcrest:*</exclude>
+ <exclude>com.github.stefanbirkner:*</exclude>
+ </excludes>
+ </artifactSet>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.apache.batchee.cli.BatchEECLI</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/cli/src/main/java/org/apache/batchee/cli/classloader/ChildFirstURLClassLoader.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/classloader/ChildFirstURLClassLoader.java b/tools/cli/src/main/java/org/apache/batchee/cli/classloader/ChildFirstURLClassLoader.java
new file mode 100644
index 0000000..c69d65f
--- /dev/null
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/classloader/ChildFirstURLClassLoader.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.batchee.cli.classloader;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class ChildFirstURLClassLoader extends URLClassLoader {
+ private final ClassLoader system;
+
+ public ChildFirstURLClassLoader(final URL[] urls, final ClassLoader parent) {
+ super(urls, parent);
+ system = ClassLoader.getSystemClassLoader();
+ }
+
+ @Override
+ public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ // already loaded?
+ Class<?> clazz = findLoadedClass(name);
+ if (clazz != null) {
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+
+ // JSE classes
+ try {
+ clazz = system.loadClass(name);
+ if (clazz != null) {
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+ } catch (ClassNotFoundException ignored) {
+ // no-op
+ }
+
+ final boolean ok = shouldSkip(name);
+ clazz = loadInternal(name, resolve);
+ if (clazz != null) {
+ return clazz;
+ }
+
+ // finally delegate
+ clazz = loadFromParent(name, resolve);
+ if (clazz != null) {
+ return clazz;
+ }
+
+ if (!ok) {
+ clazz = loadInternal(name, resolve);
+ if (clazz != null) {
+ return clazz;
+ }
+ }
+
+ throw new ClassNotFoundException(name);
+ }
+
+ // extension point for next releases but here to don't need to re-implement the login in loadClass
+ private boolean shouldSkip(final String name) {
+ return false;
+ }
+
+ private Class<?> loadFromParent(final String name, final boolean resolve) {
+ ClassLoader parent = getParent();
+ if (parent == null) {
+ parent = system;
+ }
+ try {
+ final Class<?> clazz = Class.forName(name, false, parent);
+ if (clazz != null) {
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+ } catch (ClassNotFoundException ignored) {
+ // no-op
+ }
+ return null;
+ }
+
+ private Class<?> loadInternal(final String name, final boolean resolve) {
+ try {
+ final Class<?> clazz = findClass(name);
+ if (clazz != null) {
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+ } catch (final ClassNotFoundException ignored) {
+ // no-op
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
index 3d4e621..b910732 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
@@ -17,21 +17,24 @@
package org.apache.batchee.cli.command;
import io.airlift.command.Option;
+import org.apache.batchee.cli.classloader.ChildFirstURLClassLoader;
import org.apache.batchee.cli.lifecycle.Lifecycle;
+import org.apache.batchee.cli.zip.Zips;
import org.apache.batchee.container.exception.BatchContainerRuntimeException;
import org.apache.batchee.jaxrs.client.BatchEEJAXRSClientFactory;
import org.apache.batchee.jaxrs.client.ClientConfiguration;
import org.apache.batchee.jaxrs.client.ClientSecurity;
import org.apache.batchee.jaxrs.client.ClientSslConfiguration;
+import org.apache.commons.io.FileUtils;
import javax.batch.operations.JobOperator;
import javax.batch.runtime.BatchRuntime;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
-import java.net.URLClassLoader;
import java.util.Collection;
import java.util.LinkedList;
@@ -46,6 +49,8 @@ import static java.lang.Thread.currentThread;
* by folders to be able to run them contextual using this command.
*/
public abstract class JobOperatorCommand implements Runnable {
+ // Remote config
+
@Option(name = "-url", description = "when using JAXRS the batchee resource url")
private String baseUrl = null;
@@ -88,12 +93,20 @@ public abstract class JobOperatorCommand implements Runnable {
@Option(name = "-trustManagerProvider", description = "when using JAXRS the trustManagerProvider")
private String trustManagerProvider = null;
+ // local config
+
@Option(name = "-lifecycle", description = "the lifecycle class to use")
private String lifecycle = null;
@Option(name = "-libs", description = "folder containing additional libraries, the folder is added too to the loader")
private String libs = null;
+ @Option(name = "-archive", description = "a bar archive")
+ private String archive = null;
+
+ @Option(name = "-work", description = "work directory (default to java.io.tmp)")
+ private String work = System.getProperty("batchee.home", System.getProperty("java.io.tmpdir")) + "/batchee";
+
@Option(name = "-shared-libs", description = "folder containing shared libraries, the folder is added too to the loader")
private String sharedLibs = null;
@@ -187,24 +200,73 @@ public abstract class JobOperatorCommand implements Runnable {
}
}
+ // TODO: import URLClassLoaderFirst instead of URLClassLoader
private ClassLoader createLoader(final ClassLoader parent) throws MalformedURLException {
- if (libs == null) {
- return parent;
- }
+ final Collection<URL> urls = new LinkedList<URL>();
- final File folder = new File(libs);
- if (!folder.exists()) {
- return parent;
+ if (libs != null) {
+ final File folder = new File(libs);
+ if (folder.exists()) {
+ addFolder(folder, urls);
+ }
}
// we add libs/*.jar and libs/xxx/*.jar to be able to sort libs but only one level to keep it simple
- final Collection<URL> urls = new LinkedList<URL>();
- addFolder(folder, urls);
- if (sharedLibs != null) { // add it later to let specific libs be taken before
- addFolder(new File(sharedLibs), urls);
+ if (archive != null) {
+ final File bar = new File(archive);
+ final File exploded;
+ if (bar.exists()) {
+ if (bar.isFile()) { // bar to unzip
+ exploded = new File(work, bar.getName());
+ } else if (bar.isDirectory()) { // already unpacked
+ exploded = bar;
+ } else {
+ throw new IllegalArgumentException("unsupported archive type for: '" + archive + "'");
+ }
+
+ final File timestamp = new File(exploded, "timestamp.txt");
+
+ long ts = Long.MIN_VALUE;
+ if (exploded.exists()) {
+ if (timestamp.exists()) {
+ try {
+ ts = Long.parseLong(FileUtils.readFileToString(timestamp).trim());
+ } catch (final IOException e) {
+ ts = Long.MIN_VALUE;
+ }
+ }
+ }
+
+ if (ts == Long.MIN_VALUE || ts < bar.lastModified()) {
+ explode(bar, exploded, timestamp, bar.lastModified());
+ }
+
+ // bar archives are split accross 3 folders
+ addFolder(new File(exploded, "batch/jobs"), urls);
+ addFolder(new File(exploded, "batch/classes"), urls);
+ addFolder(new File(exploded, "libs"), urls);
+ } else {
+ throw new IllegalArgumentException("'" + archive + "' doesn't exist");
+ }
}
- return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
+ final ClassLoader sharedClassLoader = createSharedClassLoader(parent);
+ if (libs == null && archive == null) {
+ return sharedClassLoader;
+ }
+ return new ChildFirstURLClassLoader(urls.toArray(new URL[urls.size()]), sharedClassLoader);
+ }
+
+ private ClassLoader createSharedClassLoader(final ClassLoader parent) throws MalformedURLException {
+ final ClassLoader usedParent;
+ if (sharedLibs != null) { // add it later to let specific libs be taken before
+ final Collection<URL> sharedUrls = new LinkedList<URL>();
+ addFolder(new File(sharedLibs), sharedUrls);
+ usedParent = new ChildFirstURLClassLoader(sharedUrls.toArray(new URL[sharedUrls.size()]), parent);
+ } else {
+ usedParent = parent;
+ }
+ return usedParent;
}
private void addFolder(File folder, Collection<URL> urls) throws MalformedURLException {
@@ -232,6 +294,16 @@ public abstract class JobOperatorCommand implements Runnable {
urls.add(folder.toURI().toURL());
}
+ private static void explode(final File source, final File target, final File timestampFile, final long time) {
+ try {
+ FileUtils.deleteDirectory(target);
+ Zips.unzip(source, target);
+ FileUtils.write(timestampFile, Long.toString(time));
+ } catch (final IOException e) {
+ // no-op
+ }
+ }
+
private static class JarFilter implements FilenameFilter {
public static final FilenameFilter INSTANCE = new JarFilter();
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/cli/src/main/java/org/apache/batchee/cli/zip/Zips.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/zip/Zips.java b/tools/cli/src/main/java/org/apache/batchee/cli/zip/Zips.java
new file mode 100644
index 0000000..d3d1acb
--- /dev/null
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/zip/Zips.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.batchee.cli.zip;
+
+import org.apache.batchee.container.exception.BatchContainerRuntimeException;
+import org.apache.commons.io.IOUtils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class Zips {
+ private static final int FILE_BUFFER_SIZE = 32768;
+ private static final int COPY_BUFFER_SIZE = 1024;
+
+ public static void unzip(final File zipFile, final File destination) throws IOException {
+ ZipInputStream in = null;
+ try {
+ mkdir(destination);
+
+ in = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile), FILE_BUFFER_SIZE));
+
+ ZipEntry entry;
+ while ((entry = in.getNextEntry()) != null) {
+ final String path = entry.getName();
+ final File file = new File(destination, path);
+
+ if (entry.isDirectory()) {
+ continue;
+ }
+
+ mkdir(file.getParentFile());
+
+ final OutputStream out = new BufferedOutputStream(new FileOutputStream(file), FILE_BUFFER_SIZE);
+ try {
+ copy(in, out);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+
+ final long lastModified = entry.getTime();
+ if (lastModified > 0) {
+ file.setLastModified(lastModified);
+ }
+
+ }
+ } catch (final IOException e) {
+ throw new IOException("Unable to unzip " + zipFile.getAbsolutePath(), e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ private static void copy(final ZipInputStream from, final OutputStream to) throws IOException {
+ final byte[] buffer = new byte[COPY_BUFFER_SIZE];
+ int length;
+ while ((length = from.read(buffer)) != -1) {
+ to.write(buffer, 0, length);
+ }
+ to.flush();
+ }
+
+ private static void mkdir(final File file) {
+ if (!file.exists() && !file.mkdirs()) {
+ throw new BatchContainerRuntimeException("Can't create " + file.getPath());
+ }
+ }
+
+ private Zips() {
+ // no-op
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/tools/maven-plugin/pom.xml b/tools/maven-plugin/pom.xml
index e32c12b..ebe4eb8 100644
--- a/tools/maven-plugin/pom.xml
+++ b/tools/maven-plugin/pom.xml
@@ -18,72 +18,86 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
+ <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>batchee-tools</artifactId>
- <groupId>org.apache.batchee</groupId>
- <version>0.1-incubating-SNAPSHOT</version>
- </parent>
+ <parent>
+ <artifactId>batchee-tools</artifactId>
+ <groupId>org.apache.batchee</groupId>
+ <version>0.1-incubating-SNAPSHOT</version>
+ </parent>
- <artifactId>batchee-maven-plugin</artifactId>
- <name>BatchEE :: Tools :: Maven Plugin</name>
- <packaging>maven-plugin</packaging>
+ <artifactId>batchee-maven-plugin</artifactId>
+ <name>BatchEE :: Tools :: Maven Plugin</name>
+ <packaging>maven-plugin</packaging>
- <dependencies>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-jbatch_1.0_spec</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.batchee</groupId>
- <artifactId>batchee-jbatch</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.batchee</groupId>
- <artifactId>batchee-jaxrs-client</artifactId>
- <version>${project.version}</version>
- </dependency>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jbatch_1.0_spec</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.batchee</groupId>
+ <artifactId>batchee-jbatch</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.batchee</groupId>
+ <artifactId>batchee-jaxrs-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
- <dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-plugin-api</artifactId>
- <version>3.0.5</version>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.plugin-tools</groupId>
- <artifactId>maven-plugin-annotations</artifactId>
- <version>3.2</version>
- </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-archiver</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>3.2</version>
+ </dependency>
- <dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- </dependency>
- </dependencies>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ </dependency>
+ </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-plugin-plugin</artifactId>
- <version>3.2</version>
- <executions>
- <execution>
- <id>mojo-descriptor</id>
- <goals>
- <goal>descriptor</goal>
- <goal>helpmojo</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <goalPrefix>batchee</goalPrefix>
- <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>3.2</version>
+ <executions>
+ <execution>
+ <id>mojo-descriptor</id>
+ <goals>
+ <goal>descriptor</goal>
+ <goal>helpmojo</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <goalPrefix>batchee</goalPrefix>
+ <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <properties>
+ <maven.version>3.0.5</maven.version>
+ </properties>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/maven-plugin/src/main/java/org/apache/batchee/tools/maven/BarMojo.java
----------------------------------------------------------------------
diff --git a/tools/maven-plugin/src/main/java/org/apache/batchee/tools/maven/BarMojo.java b/tools/maven-plugin/src/main/java/org/apache/batchee/tools/maven/BarMojo.java
new file mode 100644
index 0000000..080b4f3
--- /dev/null
+++ b/tools/maven-plugin/src/main/java/org/apache/batchee/tools/maven/BarMojo.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.batchee.tools.maven;
+
+import org.apache.maven.ProjectDependenciesResolver;
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+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;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.util.DefaultFileSet;
+import org.codehaus.plexus.components.io.fileselectors.FileInfo;
+import org.codehaus.plexus.components.io.fileselectors.FileSelector;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+
+/**
+ * create a bar archive using packaging bar and this plugin:
+ * <packaging>bar</packaging>
+ * <p/>
+ * <plugin>
+ * <groupId>org.apache.batchee</groupId>
+ * <artifactId>batchee-maven-plugin</artifactId>
+ * <version>0.1-incubating-SNAPSHOT</version>
+ * <extensions>true</extensions>
+ * </plugin>
+ */
+@Mojo(name = "bar", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, defaultPhase = LifecyclePhase.PACKAGE)
+public class BarMojo extends AbstractMojo {
+ private static final String JOB_XML_PATH = "META-INF/batch-jobs/";
+
+ @Component(role = Archiver.class, hint = "jar")
+ private JarArchiver jarArchiver;
+
+ @Component
+ private MavenProjectHelper helper;
+
+ @Parameter(readonly = true, defaultValue = "${project}")
+ private MavenProject project;
+
+ @Parameter(defaultValue = "${localRepository}")
+ protected ArtifactRepository localRepo;
+
+ @Parameter(defaultValue = "${project.remoteArtifactRepositories}")
+ protected List<ArtifactRepository> remoteRepos;
+
+ @Component(role = ProjectDependenciesResolver.class)
+ protected ProjectDependenciesResolver resolver;
+
+ @Parameter(defaultValue = "${session}", required = true)
+ protected MavenSession session;
+
+ @Parameter(property = "batchee.finalName", defaultValue = "${project.build.finalName}", required = true)
+ private String finalName;
+
+ @Parameter(defaultValue = "${project.build.directory}", required = true)
+ private File outputDirectory;
+
+ @Parameter(property = "batchee.classifier")
+ private String classifier;
+
+ @Parameter(property = "batchee.classes", defaultValue = "${project.build.directory}/classes")
+ private File classes;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (classifier == null && !"bar".equals(project.getPackaging())) {
+ getLog().info("Packaging type is not 'bar' so ignoring bar creation");
+ return;
+ }
+
+ final File bar = createBar();
+
+ if (classifier != null) {
+ helper.attachArtifact(project, "bar", classifier, bar);
+ } else {
+ project.getArtifact().setFile(bar);
+ }
+ }
+
+ private File createBar() throws MojoExecutionException {
+ final File target = new File(outputDirectory, finalName + (classifier != null ? classifier : "") + ".bar");
+
+ final MavenArchiver archiver = new MavenArchiver();
+ archiver.setOutputFile(target);
+ archiver.setArchiver(jarArchiver);
+
+ // lib/*
+ try {
+ for (final Artifact dependency : resolver.resolve(project, asList("compile", "runtime", "system"), session)) {
+ if ("provided".equals(dependency.getScope())) { // not sure why compile triggers provided using resolver
+ continue;
+ }
+ jarArchiver.addFile(dependency.getFile(), "libs/" + artifactPath(dependency));
+ }
+ } catch (final Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ // classes
+ if (classes.isDirectory()) {
+ final FileSelector jobSelector = new FileSelector() {
+ @Override
+ public boolean isSelected(final FileInfo fileInfo) throws IOException {
+ final String name = fileInfo.getName();
+ return name.replace('\\', '/').startsWith(JOB_XML_PATH) && name.endsWith(".xml");
+ }
+ };
+
+ final DefaultFileSet fileSet = new DefaultFileSet();
+ fileSet.setDirectory(classes);
+ fileSet.setIncludingEmptyDirectories(false);
+
+ fileSet.setPrefix("batch/classes/");
+ fileSet.setFileSelectors(new FileSelector[]{
+ new FileSelector() {
+ @Override
+ public boolean isSelected(final FileInfo fileInfo) throws IOException {
+ return !jobSelector.isSelected(fileInfo);
+ }
+ }
+ });
+ jarArchiver.addFileSet(fileSet);
+
+ fileSet.setPrefix("batch/jobs/");
+ fileSet.setFileSelectors(new FileSelector[]{ jobSelector });
+ jarArchiver.addFileSet(fileSet);
+ }
+
+ try {
+ archiver.createArchive(session, project, new MavenArchiveConfiguration());
+ } catch (final Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ return target;
+ }
+
+ // artifactId-[classifier-]version.type
+ private static String artifactPath(final Artifact artifact) {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append(artifact.getArtifactId());
+ sb.append("-");
+
+ if (artifact.hasClassifier()) {
+ sb.append(artifact.getClassifier());
+ sb.append("-");
+ }
+
+ if (artifact.getBaseVersion() != null) {
+ sb.append(artifact.getBaseVersion());
+ } else if (artifact.getVersion() != null) {
+ sb.append(artifact.getVersion());
+ } else {
+ sb.append(artifact.getVersionRange().toString());
+ }
+
+ sb.append('.').append(artifact.getType());
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/012278dd/tools/maven-plugin/src/main/resources/META-INF/plexus/components.xml
----------------------------------------------------------------------
diff --git a/tools/maven-plugin/src/main/resources/META-INF/plexus/components.xml b/tools/maven-plugin/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000..cd7eb7e
--- /dev/null
+++ b/tools/maven-plugin/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<component-set>
+ <components>
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>bar</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <phases>
+ <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
+ <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
+ <package>org.apache.batchee:batchee-maven-plugin:bar</package>
+ <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+ <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+ </phases>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>bar</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <extension>bar</extension>
+ <type>bar</type>
+ <packaging>bar</packaging>
+ </configuration>
+ </component>
+ </components>
+</component-set>