Equinox Execution
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 25 Apr 2009 08:01:20 +0000 (08:01 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 25 Apr 2009 08:01:20 +0000 (08:01 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk/maven@2347 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

maven-argeo-osgi-plugin/pom.xml
maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractBundlesPackagerMojo.java
maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractOsgiMojo.java
maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/EquinoxExecMojo.java [new file with mode: 0644]
maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/PackageBundlesMojo.java
maven-argeo-qooxdoo-plugin/pom.xml
org.argeo.slc.maven.plugin/.classpath
org.argeo.slc.maven.plugin/pom.xml
org.argeo.slc.maven.plugin/src/main/java/org/argeo/slc/maven/plugin/SystemCall.java [new file with mode: 0644]

index 5480ddb34272bcf99b18a9987c91d6231c5ac922..2a389e22b6523ef736196249ad1487fd2132696a 100644 (file)
@@ -3,11 +3,11 @@
        <parent>\r
                <groupId>org.argeo.slc.maven</groupId>\r
                <artifactId>slc-maven</artifactId>\r
-               <version>0.1.1</version>\r
+               <version>0.1.2</version>\r
                <relativePath>..</relativePath>\r
        </parent>\r
        <artifactId>maven-argeo-osgi-plugin</artifactId>\r
-       <version>0.1.4</version>\r
+       <version>0.1.5</version>\r
        <packaging>maven-plugin</packaging>\r
        <name>Argeo OSGi Plugin</name>\r
 \r
                </plugins>\r
        </build>\r
        <dependencies>\r
+               <dependency>\r
+                       <groupId>org.argeo.slc.maven</groupId>\r
+                       <artifactId>org.argeo.slc.maven.plugin</artifactId>\r
+                       <version>0.1.2</version>\r
+               </dependency>\r
                <dependency>\r
                        <groupId>org.apache.maven</groupId>\r
                        <artifactId>maven-project</artifactId>\r
index 5fc37a7765549a8bd3ce6cc4d6487c846e4322d2..f3b15fe768b618211b21aaba3db547727e582d76 100644 (file)
@@ -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);
index 30c4ffd600dc37b5eb2f2958c72bad41658523aa..063444db8a89ea89c73277390d1c97ba866a0c69 100644 (file)
@@ -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 (file)
index 0000000..b393d20
--- /dev/null
@@ -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<cmd.length;i++)
+                               System.out.print(cmd[i]);
+                       System.out.print('\n');
+                       
+                       SystemCall systemCall = new SystemCall(execDir.getCanonicalPath(),
+                                       cmd, true);
+                       systemCall.run();
+
+               } catch (Exception e) {
+                       throw new MojoExecutionException("Cannot execute Equinox", e);
+               }
+
+       }
+}
index 00da0777ea9282da42c1cb342e5e8f245c52b12e..26150fe62b62a925ba418c26c1337ac5ce42673d 100644 (file)
@@ -66,10 +66,8 @@ public class PackageBundlesMojo extends AbstractBundlesPackagerMojo {
 
                                // Write manifest
                                FileOutputStream out = new FileOutputStream(manifestFile);
-                               bundlePackage.getManifest().getMainAttributes().put(
-                                               Attributes.Name.MANIFEST_VERSION, "1.0");
 
-                               System.out.println("# BUNDLE "
+                               System.out.println("\n# BUNDLE "
                                                + bundlePackage.getArtifact().getArtifactId());
                                Attributes mainAttrs = bundlePackage.getManifest()
                                                .getMainAttributes();
index 25f8fae04b16620fa730e43fb38091584f8a7c2e..173c9889f16cfc4d3d4254b23ff5b1e1fd679f09 100644 (file)
@@ -4,11 +4,11 @@
        <parent>\r
                <groupId>org.argeo.slc.maven</groupId>\r
                <artifactId>slc-maven</artifactId>\r
-               <version>0.1.1</version>\r
+               <version>0.1.2</version>\r
                <relativePath>..</relativePath>\r
        </parent>\r
        <artifactId>maven-argeo-qooxdoo-plugin</artifactId>\r
-       <version>0.8.1.4</version>\r
+       <version>0.8.1.5</version>\r
        <packaging>maven-plugin</packaging>\r
        <name>Argeo Qooxdoo Plugin</name>\r
 \r
@@ -27,6 +27,7 @@
                <dependency>\r
                        <groupId>org.argeo.slc.maven</groupId>\r
                        <artifactId>org.argeo.slc.maven.plugin</artifactId>\r
+                       <version>0.1.2</version>\r
                </dependency>\r
                <dependency>\r
                        <groupId>org.apache.maven</groupId>\r
index 30baf1326015b0e1e881c9009d643374adafa6e4..0c1a2f0368b6dae3b742c17bf74fffb2132b326d 100644 (file)
@@ -2,7 +2,7 @@
 <classpath>
        <classpathentry kind="src" output="target/classes" path="src/main/java"/>
        <classpathentry kind="src" path="src/main/resources"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
        <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
        <classpathentry kind="output" path="target/classes"/>
 </classpath>
index 401d6880ddacf4dda0bfbe9f650650e761c7b4ed..9da0f69d1cddfa8c0a5f0f6a353524f7941b9a6d 100644 (file)
@@ -4,10 +4,11 @@
        <parent>\r
                <groupId>org.argeo.slc.maven</groupId>\r
                <artifactId>slc-maven</artifactId>\r
-               <version>0.1.1</version>\r
+               <version>0.1.2</version>\r
                <relativePath>..</relativePath>\r
        </parent>\r
        <artifactId>org.argeo.slc.maven.plugin</artifactId>\r
+       <version>0.1.2</version>\r
        <packaging>jar</packaging>\r
        <name>Argeo Maven Plugin Development Support</name>\r
 \r
                        <groupId>org.codehaus.plexus</groupId>\r
                        <artifactId>plexus-archiver</artifactId>\r
                </dependency>\r
+               <dependency>\r
+                       <groupId>commons-io</groupId>\r
+                       <artifactId>commons-io</artifactId>\r
+               </dependency>\r
+\r
        </dependencies>\r
 </project>
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 (file)
index 0000000..8d2e3a0
--- /dev/null
@@ -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);
+                               }
+                       }
+               }
+
+       }
+}