first commit
This commit is contained in:
parent
6bedeea189
commit
2c03e59fd3
|
@ -0,0 +1,15 @@
|
|||
#-*- mode: ruby -*-
|
||||
|
||||
id 'de.saumya.mojo:jruby-mains:0.1.0-SNAPSHOT'
|
||||
|
||||
scope :provided do
|
||||
pom 'org.jruby:jruby:1.7.18'
|
||||
jar 'org.eclipse.jetty:jetty-server:${jetty.version}'
|
||||
jar 'org.eclipse.jetty:jetty-webapp:${jetty.version}'
|
||||
end
|
||||
|
||||
properties 'jetty.version' => '8.1.14.v20131031', 'project.build.sourceEncoding' => 'utf-8'
|
||||
|
||||
plugin :compiler, '2.3.2', :target => '1.7', :source => '1.7'
|
||||
|
||||
properties 'tesla.dump.pom' => 'pom.xml', 'tesla.dump.readonly' => true
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.saumya.mojo</groupId>
|
||||
<artifactId>jruby-mains</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>jruby-mains</name>
|
||||
<properties>
|
||||
<jetty.version>8.1.14.v20131031</jetty.version>
|
||||
<tesla.dump.readonly>true</tesla.dump.readonly>
|
||||
<tesla.dump.pom>pom.xml</tesla.dump.pom>
|
||||
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jruby</groupId>
|
||||
<artifactId>jruby</artifactId>
|
||||
<version>1.7.18</version>
|
||||
<type>pom</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<target>1.7</target>
|
||||
<source>1.7</source>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,44 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractLauncher {
|
||||
|
||||
void main(String classesDir, String jarsDir, String... args) throws Exception {
|
||||
URL location = jarLocation();
|
||||
|
||||
List<URL> urls = new LinkedList<URL>();
|
||||
|
||||
File workingDir = processJar(classesDir, jarsDir, location, urls);
|
||||
|
||||
launchIt(urls, workingDir, args);
|
||||
}
|
||||
|
||||
abstract File processJar(String classesDir, String jarsDir, URL location,
|
||||
List<URL> urls) throws IOException;
|
||||
|
||||
URL jarLocation() {
|
||||
ProtectionDomain protectionDomain = AbstractLauncher.class.getProtectionDomain();
|
||||
return protectionDomain.getCodeSource().getLocation();
|
||||
}
|
||||
|
||||
void launchIt(List<URL> classloaderUrls, final File workingDir, String... args)
|
||||
throws ClassNotFoundException, NoSuchMethodException,
|
||||
IllegalAccessException, InvocationTargetException, IOException {
|
||||
// we want to have a clean classloader hierarchy without this classloader involved
|
||||
try(URLClassLoader loader = new URLClassLoader(classloaderUrls.toArray(new URL[classloaderUrls.size()]),
|
||||
ClassLoader.getSystemClassLoader().getParent())) {
|
||||
Class<?> main = loader.loadClass("de.saumya.mojo.mains.JRubyMain");
|
||||
Method m = main.getMethod("main", String.class, args.getClass());
|
||||
m.invoke(main, workingDir.getAbsolutePath(), (Object[]) args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class ExtractedZip {
|
||||
|
||||
static class DeleteDirectory extends SimpleFileVisitor<Path> {
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir,
|
||||
IOException exc) throws IOException {
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
private final File target;
|
||||
|
||||
public ExtractedZip(InputStream zip) throws IOException {
|
||||
target = Files.createTempDirectory("jruby-mains-").toFile();
|
||||
unzip(zip);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Files.walkFileTree(target.toPath(), new DeleteDirectory());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
File directory() {
|
||||
return target;
|
||||
}
|
||||
|
||||
private void unzip(InputStream zip) throws IOException {
|
||||
try(ZipInputStream is = new ZipInputStream(zip)){
|
||||
ZipEntry entry = is.getNextEntry();
|
||||
while (entry != null) {
|
||||
File path = new File(target, entry.getName());
|
||||
if (!entry.isDirectory()) {
|
||||
extractFile(is, path);
|
||||
} else {
|
||||
path.mkdir();
|
||||
}
|
||||
is.closeEntry();
|
||||
entry = is.getNextEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final byte[] bytesIn = new byte[4096];
|
||||
|
||||
private void extractFile(ZipInputStream in, File path) throws IOException {
|
||||
path.getParentFile().mkdirs();
|
||||
try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path))){
|
||||
int read = 0;
|
||||
while ((read = in.read(bytesIn)) != -1) {
|
||||
bos.write(bytesIn, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
public class ExtractingJarMain {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new ExtractingLauncher().main((String)null, (String)null, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
class ExtractingLauncher extends AbstractLauncher {
|
||||
File processJar(String classesDir, String jarsDir, URL location,
|
||||
List<URL> urls) throws IOException, MalformedURLException {
|
||||
final File dir;
|
||||
try(InputStream is = location.openStream()){
|
||||
ExtractedZip extractedZip = new ExtractedZip(is);
|
||||
urls.add(extractedZip.directory().toURI().toURL());
|
||||
if (classesDir == null) {
|
||||
dir = extractedZip.directory();
|
||||
}
|
||||
else {
|
||||
dir = new File(extractedZip.directory(), classesDir);
|
||||
urls.add(dir.toURI().toURL());
|
||||
}
|
||||
if (jarsDir != null) {
|
||||
for(File f: new File(extractedZip.directory(), jarsDir).listFiles()) {
|
||||
if (f.getName().endsWith(".jar")) {
|
||||
urls.add(f.toURI().toURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
public class ExtractingWarMain {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new ExtractingLauncher().main("WEB-INF/classes", "WEB-INF/lib", args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jruby.Main;
|
||||
import org.jruby.RubyInstanceConfig;
|
||||
import org.jruby.exceptions.RaiseException;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
|
||||
public class JRubyMain extends Main {
|
||||
|
||||
public static void main(String currentDir, String... args) {
|
||||
JRubyMain main = new JRubyMain(currentDir);
|
||||
try {
|
||||
Status status = main.run(args);
|
||||
if (status.isExit()) {
|
||||
System.exit(status.getStatus());
|
||||
}
|
||||
} catch (RaiseException rj) {
|
||||
System.exit(-1);//TODO handleRaiseException(rj));
|
||||
} catch (Throwable t) {
|
||||
// print out as a nice Ruby backtrace
|
||||
System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t));
|
||||
while ((t = t.getCause()) != null) {
|
||||
System.err.println("Caused by:");
|
||||
System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t));
|
||||
}
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
JRubyMain(String currentDirectory) {
|
||||
this(currentDirectory, new RubyInstanceConfig());
|
||||
}
|
||||
|
||||
JRubyMain(String currentDirectory, RubyInstanceConfig config) {
|
||||
super(config);
|
||||
config.setHardExit(true);
|
||||
config.setCurrentDirectory(currentDirectory);
|
||||
// set jruby home into classloader even if we are on filesystem
|
||||
config.setJRubyHome("uri:classloader://META-INF/jruby.home");
|
||||
Map<String, String> env = new HashMap<String, String>( System.getenv() );
|
||||
// we assume the bundled jars are placed at the root of the "archive"
|
||||
env.put("JARS_HOME", currentDirectory);
|
||||
// we assume the bundled gems are placed at the root of the "archive"
|
||||
env.put("GEM_PATH", currentDirectory);
|
||||
// needed for jruby version before 1.7.19
|
||||
env.put("BUNDLE_DISABLE_SHARED_GEMS", "true");
|
||||
config.setEnvironment(env);
|
||||
// older jruby-1.7.x does need this
|
||||
config.setLoader(JRubyMain.class.getClassLoader());
|
||||
}
|
||||
|
||||
public Status run(String[] args) {
|
||||
// require META-INF/init.rb and WEB-INF/init.rb to load any additional config
|
||||
// following warblers and jruby-rack convention
|
||||
List<String> newArgs = new ArrayList<String>(Arrays.asList(args));
|
||||
addRequire(newArgs, "META-INF/init");
|
||||
addRequire(newArgs, "WEB-INF/init");
|
||||
return super.run(newArgs.toArray(new String[newArgs.size()]));
|
||||
}
|
||||
|
||||
private void addRequire(List<String> newArgs, String name) {
|
||||
if (getClass().getClassLoader().getResource(name + ".rb") != null) {
|
||||
newArgs.add(0, "-r" + name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
public class JarMain {
|
||||
|
||||
public static void main(String... args) {
|
||||
JRubyMain.main("uri:classloader:/", args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
import java.net.URL;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.bio.SocketConnector;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
public class JettyRunMain
|
||||
{
|
||||
|
||||
public static void main(String[] args) {
|
||||
main(System.getProperties(), args);
|
||||
}
|
||||
|
||||
public static void main(Properties props, String[] args) {
|
||||
Server server = new Server();
|
||||
SocketConnector connector = new SocketConnector();
|
||||
|
||||
// Set some timeout options to make debugging easier.
|
||||
connector.setMaxIdleTime(1000 * 60 * 60);
|
||||
connector.setSoLingerTime(-1);
|
||||
connector.setPort(Integer.parseInt(props.getProperty("port", "8989")));
|
||||
connector.setHost(props.getProperty("host"));
|
||||
server.setConnectors(new Connector[] { connector });
|
||||
|
||||
WebAppContext context = new WebAppContext();
|
||||
context.setServer(server);
|
||||
context.setContextPath("/");
|
||||
context.setExtractWAR( false );
|
||||
context.setCopyWebInf( true );
|
||||
|
||||
ProtectionDomain protectionDomain = JettyRunMain.class.getProtectionDomain();
|
||||
URL location = protectionDomain.getCodeSource().getLocation();
|
||||
context.setWar(location.toExternalForm());
|
||||
|
||||
server.setHandler(context);
|
||||
Runtime.getRuntime().addShutdownHook(new JettyStop(server));
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(100);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package de.saumya.mojo.mains;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
||||
public class JettyStop extends Thread {
|
||||
|
||||
private final Server server;
|
||||
|
||||
JettyStop(Server server){
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
server.stop();
|
||||
server.join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue