diff --git a/cli/pom.xml b/cli/pom.xml
index 17fa61e21082187ed2be2473cce94eac11b9225c..3ee8bca64f41a899fedfbe3fe01ec42973b7c47a 100644
--- a/cli/pom.xml
+++ b/cli/pom.xml
@@ -10,6 +10,30 @@
cliHudson CLI
+
+
+
+ maven-assembly-plugin
+
+
+
+ attached
+
+ package
+
+ jar-with-dependencies
+
+
+ hudson.cli.CLI
+
+
+
+
+
+
+
+
+
${project.groupId}
diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java
index 6f0cb710b82ea8e42784851b3c388ba5e224fc67..daa7937a1f484e68fad1b8394ad0b1497525647d 100644
--- a/cli/src/main/java/hudson/cli/CLI.java
+++ b/cli/src/main/java/hudson/cli/CLI.java
@@ -1,19 +1,42 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004-2009, Sun Microsystems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package hudson.cli;
-import hudson.remoting.Callable;
import hudson.remoting.Channel;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.lang.reflect.Method;
/**
+ * CLI entry point to Hudson.
+ *
* @author Kohsuke Kawaguchi
*/
public class CLI {
public static void main(final String[] args) throws Exception {
- URL target = new URL("http://localhost:8080/duplexChannel");
+ URL target = new URL("http://localhost:8080/cli");
FullDuplexHttpStream con = new FullDuplexHttpStream(target);
ExecutorService pool = Executors.newCachedThreadPool();
Channel channel = new Channel("Chunked connection to "+target,
@@ -22,12 +45,8 @@ public class CLI {
// execute the command
int r=-1;
try {
- r = channel.call(new Callable() {
- public Integer call() throws Exception {
- Method m = Class.forName("hudson.model.Hudson").getMethod("cli", String[].class);
- return (Integer)m.invoke(null,new Object[]{args});
- }
- });
+ CliEntryPoint cli = (CliEntryPoint)channel.getRemoteProperty(CliEntryPoint.class.getName());
+ r = cli.main(args);
} finally {
channel.close();
pool.shutdown();
diff --git a/cli/src/main/java/hudson/cli/CliEntryPoint.java b/cli/src/main/java/hudson/cli/CliEntryPoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..61f7d4b031905c8f61bd8ce7d42da5ae1ad40987
--- /dev/null
+++ b/cli/src/main/java/hudson/cli/CliEntryPoint.java
@@ -0,0 +1,36 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004-2009, Sun Microsystems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package hudson.cli;
+
+/**
+ * Remotable interface for CLI entry point on the server side.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+public interface CliEntryPoint {
+ /**
+ * Just like the static main method.
+ */
+ int main(String[] args);
+}
diff --git a/core/pom.xml b/core/pom.xml
index 44a74ada7e9ed4c57ae8c6297dc4ea798e664440..4741c327cc393ac5e7f815ec755e341e3b91afed 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -297,10 +297,15 @@ THE SOFTWARE.
- org.jvnet.hudson.main
+ ${project.groupId}remoting${project.version}
+
+ ${project.groupId}
+ cli
+ ${project.version}
+ org.jvnet.hudsonjtidy
diff --git a/core/src/main/java/hudson/model/FullDuplexHttpChannel.java b/core/src/main/java/hudson/model/FullDuplexHttpChannel.java
index 2dd17eab730789ceac520c6868ce5b0002e02598..b77cb9406746b6ec1bcf4ff4ee11696128077111 100644
--- a/core/src/main/java/hudson/model/FullDuplexHttpChannel.java
+++ b/core/src/main/java/hudson/model/FullDuplexHttpChannel.java
@@ -1,3 +1,26 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004-2009, Sun Microsystems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package hudson.model;
import hudson.remoting.Channel;
@@ -19,7 +42,7 @@ import java.util.logging.Logger;
*
* @author Kohsuke Kawaguchi
*/
-final class FullDuplexHttpChannel {
+abstract class FullDuplexHttpChannel {
private Channel channel;
private final PipedOutputStream pipe = new PipedOutputStream();
@@ -62,10 +85,13 @@ final class FullDuplexHttpChannel {
}
};
ping.start();
+ main(channel);
channel.join();
ping.interrupt();
}
+ protected abstract void main(Channel channel) throws IOException, InterruptedException;
+
/**
* This is where we receive inputs from the client.
*/
diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java
index 7623c089a65e9235e53086725d95c10267a231dd..f3b3f9a21166ccacec4fe5fc9abe96882ae8bb80 100644
--- a/core/src/main/java/hudson/model/Hudson.java
+++ b/core/src/main/java/hudson/model/Hudson.java
@@ -44,6 +44,7 @@ import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.DescriptorExtensionList;
import hudson.ExtensionListView;
+import hudson.cli.CliEntryPoint;
import hudson.logging.LogRecorderManager;
import hudson.lifecycle.Lifecycle;
import hudson.model.Descriptor.FormException;
@@ -147,6 +148,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;
+import java.io.Serializable;
import java.net.URL;
import java.security.SecureRandom;
import java.text.NumberFormat;
@@ -2651,12 +2653,25 @@ public final class Hudson extends Node implements ItemGroup, Stapl
rsp.getWriter().println("GCed");
}
+ /**
+ * {@link CliEntryPoint} implementation exposed to the remote CLI.
+ */
+ private final class CliManager implements CliEntryPoint, Serializable {
+ public int main(String[] args) {
+ System.out.println(Arrays.asList(args));
+ return 0;
+ }
+ private Object writeReplace() {
+ return Channel.current().export(CliEntryPoint.class,this);
+ }
+ }
+
private transient final Map duplexChannels = new HashMap();
/**
- * Handles HTTP requests for duplex channels.
+ * Handles HTTP requests for duplex channels for CLI.
*/
- public void doDuplexChannel(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
+ public void doCli(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
checkPermission(READ);
requirePOST();
@@ -2664,7 +2679,11 @@ public final class Hudson extends Node implements ItemGroup, Stapl
FullDuplexHttpChannel server;
if(req.getHeader("Side").equals("download")) {
- duplexChannels.put(uuid,server=new FullDuplexHttpChannel(uuid, !hasPermission(ADMINISTER)));
+ duplexChannels.put(uuid,server=new FullDuplexHttpChannel(uuid, !hasPermission(ADMINISTER)) {
+ protected void main(Channel channel) throws IOException, InterruptedException {
+ channel.setProperty(CliEntryPoint.class.getName(),new CliManager());
+ }
+ });
try {
server.download(req,rsp);
} finally {
@@ -2675,14 +2694,6 @@ public final class Hudson extends Node implements ItemGroup, Stapl
}
}
- /**
- * Called by the CLI over a {@link Channel} to execute an CLI command.
- */
- public static int cli(String... args) {
- System.out.println(Arrays.asList(args));
- return 0;
- }
-
/**
* Binds /userContent/... to $HUDSON_HOME/userContent.
*/
diff --git a/remoting/src/main/java/hudson/remoting/Channel.java b/remoting/src/main/java/hudson/remoting/Channel.java
index 9ec029faf7d2ddb029cc6eb205b542afec0bee29..e881095b8599923401dfaa758ed6dcd86db42829 100644
--- a/remoting/src/main/java/hudson/remoting/Channel.java
+++ b/remoting/src/main/java/hudson/remoting/Channel.java
@@ -97,7 +97,7 @@ import java.net.URL;
*
* @author Kohsuke Kawaguchi
*/
-public class Channel implements VirtualChannel {
+public class Channel implements VirtualChannel, IChannel {
private final ObjectInputStream ois;
private final ObjectOutputStream oos;
private final String name;
@@ -173,6 +173,16 @@ public class Channel implements VirtualChannel {
*/
public final AtomicInteger resourceLoadingCount = new AtomicInteger();
+ /**
+ * Property bag that contains application-specific stuff.
+ */
+ private final Hashtable