From b7dce07a88a8a1451b332bc97d979c844c5abccb Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 25 Apr 2009 08:01:20 +0000 Subject: [PATCH] Equinox Execution git-svn-id: https://svn.argeo.org/slc/trunk/maven@2347 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- maven-argeo-osgi-plugin/pom.xml | 9 +- .../osgi/AbstractBundlesPackagerMojo.java | 25 +- .../maven/plugins/osgi/AbstractOsgiMojo.java | 10 + .../maven/plugins/osgi/EquinoxExecMojo.java | 188 ++++++++++++++ .../plugins/osgi/PackageBundlesMojo.java | 4 +- maven-argeo-qooxdoo-plugin/pom.xml | 5 +- org.argeo.slc.maven.plugin/.classpath | 2 +- org.argeo.slc.maven.plugin/pom.xml | 8 +- .../argeo/slc/maven/plugin/SystemCall.java | 236 ++++++++++++++++++ 9 files changed, 468 insertions(+), 19 deletions(-) create mode 100644 maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/EquinoxExecMojo.java create mode 100644 org.argeo.slc.maven.plugin/src/main/java/org/argeo/slc/maven/plugin/SystemCall.java diff --git a/maven-argeo-osgi-plugin/pom.xml b/maven-argeo-osgi-plugin/pom.xml index 5480ddb34..2a389e22b 100644 --- a/maven-argeo-osgi-plugin/pom.xml +++ b/maven-argeo-osgi-plugin/pom.xml @@ -3,11 +3,11 @@ org.argeo.slc.maven slc-maven - 0.1.1 + 0.1.2 .. maven-argeo-osgi-plugin - 0.1.4 + 0.1.5 maven-plugin Argeo OSGi Plugin @@ -30,6 +30,11 @@ + + org.argeo.slc.maven + org.argeo.slc.maven.plugin + 0.1.2 + org.apache.maven maven-project diff --git a/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractBundlesPackagerMojo.java b/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractBundlesPackagerMojo.java index 5fc37a776..f3b15fe76 100644 --- a/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractBundlesPackagerMojo.java +++ b/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractBundlesPackagerMojo.java @@ -6,8 +6,11 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.jar.Attributes; import java.util.jar.Manifest; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; @@ -18,15 +21,6 @@ import org.apache.maven.project.MavenProject; */ public abstract class AbstractBundlesPackagerMojo extends AbstractOsgiMojo { - /** - * The maven project. - * - * @parameter expression="${project}" - * @required - * @readonly - */ - protected MavenProject project; - /** * Directory of the simple bundles * @@ -70,6 +64,14 @@ public abstract class AbstractBundlesPackagerMojo extends AbstractOsgiMojo { File destFile = new File(packagedBundlesDir.getPath() + File.separator + artifactId + ".jar"); try { + String manifestStr = FileUtils.readFileToString(manifestFile); + char lastChar = manifestStr.charAt(manifestStr.length() - 1); + if (lastChar != '\n') + throw new RuntimeException( + "Manifest " + + manifestFile + + " is not valid, it does not end with and endline character."); + Manifest manifest = readManifest(manifestFile); // Symbolic name String symbolicNameMf = manifest.getMainAttributes().getValue( @@ -122,10 +124,13 @@ public abstract class AbstractBundlesPackagerMojo extends AbstractOsgiMojo { manifest.getMainAttributes().putValue("Bundle-Version", newVersionMf); + manifest.getMainAttributes().put( + Attributes.Name.MANIFEST_VERSION, "1.0"); + Artifact artifact = artifactFactory.createBuildArtifact(project .getGroupId(), artifactId, newVersionArt, "jar"); BundlePackage bundlePackage = new BundlePackage(artifact, dir, - manifest, destFile); + new Manifest(manifest), destFile); list.add(bundlePackage); } catch (Exception e) { throw new MojoExecutionException("Could not analyze " + dir, e); diff --git a/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractOsgiMojo.java b/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractOsgiMojo.java index 30c4ffd60..063444db8 100644 --- a/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractOsgiMojo.java +++ b/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractOsgiMojo.java @@ -4,11 +4,21 @@ import java.io.File; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.project.MavenProject; /** * Factorize common configuration */ public abstract class AbstractOsgiMojo extends AbstractMojo { + /** + * The maven project. + * + * @parameter expression="${project}" + * @required + * @readonly + */ + protected MavenProject project; + /** * List of Remote Repositories used by the resolver * diff --git a/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/EquinoxExecMojo.java b/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/EquinoxExecMojo.java new file mode 100644 index 000000000..b393d20b3 --- /dev/null +++ b/maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/EquinoxExecMojo.java @@ -0,0 +1,188 @@ +package org.argeo.slc.maven.plugins.osgi; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.argeo.slc.maven.plugin.SystemCall; + +/** + * @goal equinox-exec + * */ +public class EquinoxExecMojo extends AbstractOsgiMojo { + /** + * Used to look up Artifacts in the remote repository. + * + * @parameter expression= + * "${component.org.apache.maven.artifact.resolver.ArtifactResolver}" + * @required + * @readonly + */ + protected org.apache.maven.artifact.resolver.ArtifactResolver resolver; + + /** + * Used to look up Artifacts in the remote repository. + * + * @parameter expression= + * "${component.org.apache.maven.artifact.factory.ArtifactFactory}" + * @required + * @readonly + */ + protected org.apache.maven.artifact.factory.ArtifactFactory factory; + + /** @component */ + private ArtifactMetadataSource artifactMetadataSource; + + /** + * Equinox artifact id + * + * @parameter expression="${equinoxArtifactId}" + * default-value="org.eclipse.osgi" + * @required + */ + protected String equinoxArtifactId; + + /** + * OSGIBoot artifact id + * + * @parameter expression="${osgiBootArtifactId}" + * default-value="org.argeo.slc.osgiboot" + * @required + */ + protected String osgiBootArtifactId; + + /** + * Java executable + * + * @parameter expression="${jvm}" default-value="java" + * @required + */ + protected String jvm; + + /** + * JVM arguments + * + * @parameter alias="${jvmArgs}" + */ + protected String[] jvmArgs; + + protected String[] defaultJvmArgs = { "-Xmx256m" }; + + /** + * Equinox args + * + * @parameter alias="${args}" + */ + protected String[] args; + + protected String[] defaultArgs = { "-clean", "-console", "-configuration", + "conf" }; + + /** + * Execution directory + * + * @parameter expression="${execDir}" + * @required + */ + protected File execDir; + + public void execute() throws MojoExecutionException, MojoFailureException { + try { + Artifact equinoxArtifact = null; + Artifact osgiBootArtifact = null; + + Set artifacts = project.createArtifacts(this.factory, null, null); + + ArtifactResolutionResult arr = resolver.resolveTransitively( + artifacts, project.getArtifact(), local, remoteRepos, + artifactMetadataSource, null); + // Order, just for display + Set dependencies = new TreeSet(new Comparator() { + public int compare(Object o1, Object o2) { + Artifact a1 = (Artifact) o1; + Artifact a2 = (Artifact) o2; + + if (!a1.getGroupId().equals(a2.getGroupId())) + return a1.getGroupId().compareTo(a2.getGroupId()); + else + return a1.getArtifactId().compareTo(a2.getArtifactId()); + } + }); + dependencies.addAll(arr.getArtifacts()); + + StringBuffer osgiLocations = new StringBuffer(); + List bundleArtifacts = new ArrayList(); + boolean first = true; + // Set dependencies = project.getArtifacts(); + for (Iterator it = dependencies.iterator(); it.hasNext();) { + Artifact depArtifact = (Artifact) it.next(); + System.out.println(depArtifact.getGroupId() + ":" + + depArtifact.getArtifactId() + ":" + + depArtifact.getType() + ":" + + depArtifact.getVersion() + " (" + + depArtifact.getFile() + ")"); + if (depArtifact.getArtifactId().equals(equinoxArtifactId)) + equinoxArtifact = depArtifact; + else if (depArtifact.getArtifactId().equals(osgiBootArtifactId)) + osgiBootArtifact = depArtifact; + else { + bundleArtifacts.add(depArtifact); + + if (first) + first = false; + else + osgiLocations.append(File.pathSeparatorChar); + osgiLocations.append(depArtifact.getFile() + .getCanonicalPath() + .replace(File.separatorChar, '/')); + } + } + + + // Set defaults + if(jvmArgs==null) + jvmArgs=defaultJvmArgs; + if(args==null) + args=defaultArgs; + + + List cmdList = new ArrayList(); + cmdList.add(jvm); + cmdList.addAll(Arrays.asList(jvmArgs)); + cmdList.add("-Dosgi.bundles=" + + osgiBootArtifact.getFile().getCanonicalPath() + "@start"); + cmdList.add("-Dslc.osgi.locations=" + osgiLocations); + cmdList.add("-jar"); + cmdList.add(equinoxArtifact.getFile().getCanonicalPath()); + cmdList.addAll(Arrays.asList(args)); + + String[] cmd = (String[])cmdList.toArray(new String[0]); + +// String cmdOld = jvm + " " + jvmArgs + " " + "-Dosgi.bundles=" +// + osgiBootArtifact.getFile().getCanonicalPath() + "@start " +// + "-Dslc.osgi.locations=" + osgiLocations + " -jar " +// + equinoxArtifact.getFile().getCanonicalPath() + " " + args; + for(int i=0;i org.argeo.slc.maven slc-maven - 0.1.1 + 0.1.2 .. maven-argeo-qooxdoo-plugin - 0.8.1.4 + 0.8.1.5 maven-plugin Argeo Qooxdoo Plugin @@ -27,6 +27,7 @@ org.argeo.slc.maven org.argeo.slc.maven.plugin + 0.1.2 org.apache.maven diff --git a/org.argeo.slc.maven.plugin/.classpath b/org.argeo.slc.maven.plugin/.classpath index 30baf1326..0c1a2f036 100644 --- a/org.argeo.slc.maven.plugin/.classpath +++ b/org.argeo.slc.maven.plugin/.classpath @@ -2,7 +2,7 @@ - + diff --git a/org.argeo.slc.maven.plugin/pom.xml b/org.argeo.slc.maven.plugin/pom.xml index 401d6880d..9da0f69d1 100644 --- a/org.argeo.slc.maven.plugin/pom.xml +++ b/org.argeo.slc.maven.plugin/pom.xml @@ -4,10 +4,11 @@ org.argeo.slc.maven slc-maven - 0.1.1 + 0.1.2 .. org.argeo.slc.maven.plugin + 0.1.2 jar Argeo Maven Plugin Development Support @@ -31,5 +32,10 @@ org.codehaus.plexus plexus-archiver + + commons-io + commons-io + + diff --git a/org.argeo.slc.maven.plugin/src/main/java/org/argeo/slc/maven/plugin/SystemCall.java b/org.argeo.slc.maven.plugin/src/main/java/org/argeo/slc/maven/plugin/SystemCall.java new file mode 100644 index 000000000..8d2e3a0d8 --- /dev/null +++ b/org.argeo.slc.maven.plugin/src/main/java/org/argeo/slc/maven/plugin/SystemCall.java @@ -0,0 +1,236 @@ +package org.argeo.slc.maven.plugin; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.List; + +import org.apache.commons.io.IOUtils; + +public class SystemCall implements Runnable { + private String execDir; + + private String cmd = null; + private String[] command = null; + + private boolean synchronous = true; + private boolean captureStdIn = false; + + public SystemCall() { + + } + + public SystemCall(String execDir, String cmd, boolean captureStdIn) { + super(); + this.execDir = execDir; + this.cmd = cmd; + this.synchronous = true; + this.captureStdIn = captureStdIn; + } + + public SystemCall(String execDir, String[] command, boolean captureStdIn) { + super(); + this.execDir = execDir; + this.command = command; + this.synchronous = true; + this.captureStdIn = captureStdIn; + } + + public void run() { + try { + // Execution directory + File dir = null; + if (execDir != null) { + // Replace '/' by local file separator, for portability + execDir.replace('/', File.separatorChar); + dir = new File(execDir).getCanonicalFile(); + } + + final Process process; + + if (cmd != null) { + process = Runtime.getRuntime().exec(cmd, null, dir); + } else if (command != null) { + process = Runtime.getRuntime().exec(command, null, dir); + ; + } else { + throw new RuntimeException("No command specified"); + } + + Runtime.getRuntime().addShutdownHook(new Thread() { + + public void run() { + if (process != null) { + try { + process.exitValue(); + } catch (Exception e) { + process.destroy(); + System.err.println("Killed process " + process); + } + } + } + }); + + // Manage standard streams + StreamReaderThread stdOutThread = new StreamReaderThread(process + .getInputStream(), false); + stdOutThread.start(); + // TODO: understand why streams are not properly flushed + StreamReaderThread stdErrThread = new StreamReaderThread(process + .getInputStream(), false); + stdErrThread.start(); + if (captureStdIn) + new StdInThread(process.getOutputStream()).start(); + + // Wait for the end of the process + if (synchronous) { + int exitCode = process.waitFor(); + if (exitCode != 0) { + Thread.sleep(5000);// leave the process a chance to log + System.err.println("Process return exit code " + exitCode); + } + } else { + // asynchronous: return + } + } catch (Exception e) { + throw new RuntimeException("Could not execute command " + cmd, e); + } + + } + + /** + * Shortcut method returning the current exec dir if the specified one is + * null. + */ + private String getUsedDir(File dir) { + if (dir == null) + return System.getProperty("user.dir"); + else + return dir.getPath(); + } + + public void setCmd(String command) { + this.cmd = command; + } + + public void setExecDir(String execdir) { + this.execDir = execdir; + } + + public void setCommand(String[] command) { + this.command = command; + } + + protected synchronized void write(String str, boolean isErr) { + if (isErr) { + System.err.print(str); + System.err.flush(); + } else { + System.out.print(str); + System.out.flush(); + } + notifyAll(); + } + + protected class StreamReaderThread extends Thread { + private final InputStream stream; + private final boolean isErr; + + public StreamReaderThread(InputStream stream, boolean isErr) { + this.stream = stream; + this.isErr = isErr; + } + + public void run() { + // BufferedReader in = null; + InputStreamReader isr = null; + try { + isr = new InputStreamReader(stream); + int c; + StringBuffer buf = new StringBuffer(256); + char lastCr = '\n'; + while ((c = isr.read()) != -1) { + char cr = (char) c; + + buf.append(cr); + + boolean write = false; + if (lastCr == '>' && cr == ' ') + write = true; + else if (cr == '\n') + write = true; + + lastCr = cr; + if (write) { + write(buf.toString(), isErr); + buf = new StringBuffer(256); + } + + // if (isErr) { + // System.err.print(cr); + // if (cr == '\n' || cr == '>') + // System.err.flush(); + // } else { + // System.out.print(cr); + // if (cr == '\n' || cr == '>') + // System.out.flush(); + // } + } + // String line = null; + // while ((line = in.readLine()) != null) { + // stdOutCallback(line); + // System.out. + // } + } catch (IOException e) { + // catch silently + // because the other methods + // to check whether the stream + // is closed would probably + // be to costly + } finally { + if (synchronous) + IOUtils.closeQuietly(isr); + } + } + } + + protected class StdInThread extends Thread { + private final OutputStream stream; + + public StdInThread(OutputStream stream) { + this.stream = stream; + } + + public void run() { + // BufferedReader in = null; + // Writer out = null; + InputStreamReader isr = null; + try { + // out = new OutputStreamWriter(stream); + isr = new InputStreamReader(System.in); + int c; + while ((c = isr.read()) != -1) { + stream.write(c); + stream.flush(); + } + + /* + * in = new BufferedReader(new InputStreamReader(System.in)); + * String line = null; while ((line = in.readLine()) != null) { + * out.write(line); out.write("\n"); out.flush(); } + */ + } catch (IOException e) { + throw new RuntimeException("Could not write to stdin stream", e); + } finally { + if (synchronous) { + IOUtils.closeQuietly(isr); + // IOUtils.closeQuietly(in); + // IOUtils.closeQuietly(out); + } + } + } + + } +} -- 2.39.2