first commit

This commit is contained in:
Christian Meier 2015-01-12 10:53:38 +00:00
parent 6bedeea189
commit 2c03e59fd3
11 changed files with 394 additions and 0 deletions

15
Mavenfile Normal file
View File

@ -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

48
pom.xml Normal file
View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,9 @@
package de.saumya.mojo.mains;
public class JarMain {
public static void main(String... args) {
JRubyMain.main("uri:classloader:/", args);
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}