Merge pull request #7 from mkristian/jems-classloader

POC JemsClassLoader
This commit is contained in:
R. Tyler Croy 2015-08-15 11:56:12 -07:00
commit b19ea27e16
11 changed files with 106 additions and 10 deletions

View File

@ -23,9 +23,9 @@ repositories {
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.12+'
compile 'org.slf4j:slf4j-api:1.7.12'
/* using the simple logger at runtime, no need for it at compile time though */
runtime 'org.slf4j:slf4j-simple:1.7.12+'
runtime 'org.slf4j:slf4j-simple:1.7.12'
/* Used for processing yaml files inside of gems */
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.5.4'
@ -33,8 +33,8 @@ dependencies {
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4'
/* shrinkwrap is used for digging into archives */
compile "org.jboss.shrinkwrap:shrinkwrap-bom:1.2.2+"
compile "org.jboss.shrinkwrap:shrinkwrap-depchain:1.2.2+"
compile "org.jboss.shrinkwrap:shrinkwrap-bom:1.2.2"
compile "org.jboss.shrinkwrap:shrinkwrap-depchain:1.2.2"
testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
testCompile 'org.apache.commons:commons-io:1.3.2+'

14
gem/jems.gemspec Normal file
View File

@ -0,0 +1,14 @@
#-*- mode: ruby -*-
Gem::Specification.new do |s|
s.name = 'jems'
s.version = '0.1.5'
s.authors = ['Christian Meier']
s.summary = 'JRuby Jems'
s.files = ['jems.gemspec', 'lib/jems.rb']
s.platform = 'java'
s.requirements << "jar com.github.jrubygradle:jem, #{s.version}"
s.add_runtime_dependency 'jar-dependencies', '~> 0.1.15'
end
# vim: syntax=Ruby

34
gem/lib/jems.rb Normal file
View File

@ -0,0 +1,34 @@
require 'jems_jars'
module Jems
def self.jems_class_loader
@class_loader ||= com.github.jrubygradle.jem.JemsClassLoader.create
end
def self.activate( gem )
gemspec_raw = jems_class_loader.add_jem( gem )
gemspec = eval( gemspec_raw.to_ruby )
return false if Gem.loaded_specs[ gemspec.name ]
gem_name = 'gems/' + gemspec.full_name + '/.jrubydir'
url = jems_class_loader.get_resource( gem_name )
base = "uri:#{url.to_s.sub(/.jrubydir$/, '')}"
added = false
gemspec.require_paths.each do |path|
fullpath = File.join( base, path )
if File.directory?(fullpath) and not $LOAD_PATH.member?(fullpath)
# TODO rubygems insert before 'site_ruby' entry of the LOAD_PATH
$LOAD_PATH.unshift fullpath
added = true
end
end
# TODO check if gemspec.activate does the job better
if added
Gem.loaded_specs[ gemspec.name ] = gemspec
end
added
end
end

View File

@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

View File

@ -0,0 +1,50 @@
package com.github.jrubygradle.jem;
import com.github.jrubygradle.jem.internal.GemInstaller;
import com.github.jrubygradle.jem.GemInstaller.DuplicateBehavior;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.util.Collections;
/**
* Created by cmeier on 8/15/15.
*/
public class JemsClassLoader extends URLClassLoader {
private final File jemsDir;
public static JemsClassLoader create() throws IOException {
return new JemsClassLoader(Files.createTempDirectory("jems").toFile());
}
public JemsClassLoader(File jemsDir) throws IOException {
super(new URL[] { jemsDir.toURI().toURL() });
this.jemsDir = jemsDir;
}
public Gem addJem(String jem) throws IOException {
return addJem(new File(jem));
}
public Gem addJem(File jem) throws IOException {
GemInstaller installer = new GemInstaller(jemsDir.getAbsolutePath(), Collections.<File>emptyList());
installer.mkdirs();
Gem gemspec = installer.installGem(jemsDir, jem, DuplicateBehavior.OVERWRITE);
String dir = "gems/" + installer.gemFullName(gemspec);
createDirInfoFile(dir);
for(String path: gemspec.requirePaths){
createDirInfoFile(dir + "/" + path);
}
return gemspec;
}
private void createDirInfoFile(String dir) throws IOException {
try (FileWriter out = new FileWriter(new File(jemsDir, dir + "/.jrubydir"))){
out.append(".");
}
}
}

View File

@ -50,14 +50,14 @@ public class GemInstaller {
}
}
public boolean installGem(File installDir, File gem, DuplicateBehavior onDuplicate) {
public Gem installGem(File installDir, File gem, DuplicateBehavior onDuplicate) {
/* TODO: isValidGem? */
try {
cacheGemInInstallDir(installDir, gem);
}
catch (IOException ex) {
logger.error("Failed to cache our gem in %s", installDir, ex);
return false;
return null;
}
Gem gemMetadata;
@ -73,7 +73,7 @@ public class GemInstaller {
}
catch (IOException ex) {
logger.error("Failed to process the metadata", ex);
return false;
return null;
}
logger.info(String.format("We've processed metadata for %s at version %s",
gemMetadata.name, gemMetadata.version.version));
@ -96,7 +96,7 @@ public class GemInstaller {
gemMetadata.name, installDir), ex);
}
return true;
return gemMetadata;
}
/**

View File

@ -6,7 +6,6 @@ import spock.lang.*
import java.nio.file.Files
import java.nio.file.Path
import org.apache.commons.io.FileUtils
class GemInstallerSpec extends Specification {
static final String FIXTURES_ROOT = new File(['src', 'test', 'resources'].join(File.separator)).absolutePath