All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.saumya.mojo.jruby.AbstractJRubyMojo Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
package de.saumya.mojo.jruby;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.NoSuchRealmException;

import de.saumya.mojo.ruby.Logger;
import de.saumya.mojo.ruby.script.ScriptException;
import de.saumya.mojo.ruby.script.ScriptFactory;

/**
 * Base for all JRuby mojos.
 *
 * @requiresProject false
 */
public abstract class AbstractJRubyMojo extends AbstractMojo {

    protected static final String JRUBY_COMPLETE = "jruby-complete";

    protected static final String JRUBY_CORE = "jruby-core";

    protected static final String JRUBY_STDLIB = "jruby-stdlib";

    protected static final String DEFAULT_JRUBY_VERSION = "1.7.12";


    /**
     * common arguments
     * 
* Command line -Dargs=... * * @parameter expression="${args}" */ protected String args; /** * jvm arguments for the java command executing jruby *
* Command line -Djruby.jvmargs=... * * @parameter expression="${jruby.jvmargs}" */ protected String jrubyJvmArgs; /** * switches for the jruby command, like '--1.9' *
* Command line -Djruby.switches=... * * @parameter expression="${jruby.switches}" */ protected String jrubySwitches; /** * environment values passed on to the jruby process. needs jrubyFork true. *
* @parameter */ protected Map env; /** * if the pom.xml has no runtime dependency to a jruby-complete.jar then * this version is used to resolve the jruby-complete dependency from the * local/remote maven repository. it overwrites the jruby version from * the dependencies if any. i.e. you can easily switch jruby version from the commandline ! *
* default: 1.7.12 *
* Command line -Djruby.version=... * * @parameter expression="${jruby.version}" */ private String jrubyVersion; /** * fork the JRuby execution. *
* Command line -Djruby.fork=... * * @parameter expression="${jruby.fork}" default-value="true" */ protected boolean jrubyFork; /** * verbose jruby related output *
* Command line -Djruby.verbose=... * * @parameter expression="${jruby.verbose}" default-value="false" */ protected boolean jrubyVerbose; /** * directory with ruby sources - added to java classpath and ruby loadpath *
* Command line -Djruby.sourceDirectory=... * * @parameter expression="${jruby.sourceDirectory}" default-value="src/main/ruby" */ protected File rubySourceDirectory; /** * directory with ruby sources - added to ruby loadpath only *
* Command line -Djruby.lib=... * * @parameter expression="${jruby.lib}" default-value="lib" */ protected File libDirectory; /** * the launch directory for the JRuby execution. *
* Command line -Djruby.launchDirectory=... * * @parameter default-value="${project.basedir}" expression="${jruby.launchDirectory}" */ private File launchDirectory; /** * reference to maven project for internal use. * * @parameter expression="${project}" * @required * @readOnly */ protected MavenProject project; /** * local repository for internal use. * * @parameter default-value="${localRepository}" * @required * @readonly */ protected ArtifactRepository localRepository; /** * classrealm for internal use. * * @parameter expression="${dummyExpression}" * @readonly */ protected ClassRealm classRealm; /** @component */ protected RepositorySystem repositorySystem; protected Logger logger; protected ScriptFactory factory; private JRubyVersion jRubyVersion; protected JRubyVersion getJrubyVersion() { if (jRubyVersion == null ) { this.jRubyVersion = new JRubyVersion( jrubyVersion == null ? DEFAULT_JRUBY_VERSION : jrubyVersion ); } return jRubyVersion; } private ScriptFactory newScriptFactory() throws MojoExecutionException { ScriptFactory factory = createScriptFactory(); if( env != null ){ for( Map.Entry entry: env.entrySet() ){ factory.addEnv( entry.getKey(), entry.getValue() ); } } return factory; } private ScriptFactory createScriptFactory() throws MojoExecutionException { try { classRealm.getWorld().disposeRealm("jruby-all"); } catch( NoSuchRealmException ignore ) { // ignore } try { ClassRealm realm = classRealm.getWorld().newRealm("jruby-all"); for (String path : this.project.getTestClasspathElements()) { realm.addConstituent(new File(path).toURI().toURL()); } if (this.jrubyVersion != null) { // preference to command line or property version return newScriptFactory( resolveJRubyCompleteArtifact(this.jrubyVersion) ); } // check if there is jruby present Class clazz = realm.loadClass("org.jruby.runtime.Constants"); if ( jrubyVerbose ){ String version = clazz.getField( "VERSION" ).get(clazz).toString(); getLog().info("found jruby on classpath"); getLog().info("jruby version : " + version); } this.classRealm = realm; return newScriptFactory( null ); } catch (final Exception e) { //TODO debug //e.printStackTrace(); try { return newScriptFactory(resolveJRubyArtifact()); } catch (final DependencyResolutionRequiredException ee) { throw new MojoExecutionException("could not resolve jruby", e); } } } protected ScriptFactory newScriptFactory(Artifact artifact) throws MojoExecutionException { try { final ScriptFactory factory = artifact == null ? new ScriptFactory(this.logger, this.classRealm, null, this.project.getTestClasspathElements(), this.jrubyFork): (JRUBY_CORE.equals(artifact.getArtifactId()) ? new ScriptFactory(this.logger, this.classRealm, artifact.getFile(), resolveJRubyStdlibArtifact(artifact).getFile(), this.project.getTestClasspathElements(), this.jrubyFork) : new ScriptFactory(this.logger, this.classRealm, artifact.getFile(), this.project.getTestClasspathElements(), this.jrubyFork) ); if(libDirectory != null && libDirectory.exists()){ if(jrubyVerbose){ getLog().info("add to ruby loadpath: " + libDirectory.getAbsolutePath()); } // add it to the load path for all scripts using that factory factory.addSwitch("-I", libDirectory.getAbsolutePath()); } if(rubySourceDirectory != null && rubySourceDirectory.exists()){ if(jrubyVerbose){ getLog().info("add to ruby loadpath: " + rubySourceDirectory.getAbsolutePath()); } // add it to the load path for all scripts using that factory factory.addSwitch("-I", rubySourceDirectory.getAbsolutePath()); } return factory; } catch (final DependencyResolutionRequiredException e) { throw new MojoExecutionException("could not resolve jruby", e); } catch (final ScriptException e) { throw new MojoExecutionException( "could not initialize script factory", e); } catch (final IOException e) { throw new MojoExecutionException( "could not initialize script factory", e); } } public void execute() throws MojoExecutionException, MojoFailureException { System.setProperty("jbundle.skip", "true"); this.logger = new MojoLogger(this.jrubyVerbose, getLog()); this.factory = newScriptFactory(); // skip installing jars via jbundler this.factory.addEnv("JBUNDLE_SKIP", "true"); // skip installing jars via jar-dependencies this.factory.addEnv("JARS_SKIP", "true"); this.factory.addJvmArgs(this.jrubyJvmArgs); this.factory.addSwitches(this.jrubySwitches); if(rubySourceDirectory != null && rubySourceDirectory.exists()){ if(jrubyVerbose){ getLog().info("add to java classpath: " + rubySourceDirectory.getAbsolutePath()); } // add it to the classpath so java classes can find the ruby files Resource resource = new Resource(); resource.setDirectory(rubySourceDirectory.getAbsolutePath()); project.getBuild().getResources().add(resource); } try { executeJRuby(); } catch (final IOException e) { throw new MojoExecutionException("error in executing jruby", e); } catch (final ScriptException e) { throw new MojoExecutionException("error in executing jruby", e); } } abstract protected void executeJRuby() throws MojoExecutionException, MojoFailureException, IOException, ScriptException; protected File launchDirectory() { if (this.launchDirectory == null) { this.launchDirectory = this.project.getBasedir(); if (this.launchDirectory == null || !this.launchDirectory.exists()) { this.launchDirectory = new File(System.getProperty("user.dir")); } } return this.launchDirectory; } protected Artifact resolveJRubyCompleteArtifact(final String version) throws DependencyResolutionRequiredException { getLog().debug("resolve jruby for version " + version); final Artifact artifact = this.repositorySystem.createArtifact( "org.jruby", JRUBY_COMPLETE, version, "jar"); return resolveJRubyArtifact(artifact); } private Artifact resolveJRubyArtifact(final Artifact artifact) throws DependencyResolutionRequiredException { final ArtifactResolutionRequest request = new ArtifactResolutionRequest(); request.setArtifact(artifact); request.setLocalRepository(this.localRepository); request.setRemoteRepositories(this.project.getRemoteArtifactRepositories()); this.repositorySystem.resolve(request); if (this.jrubyVerbose) { getLog().info("jruby version : " + artifact.getVersion()); } // set it so other plugins can retrieve the version in use this.jrubyVersion = artifact.getVersion(); return artifact; } protected Artifact resolveJRubyArtifact() throws DependencyResolutionRequiredException, MojoExecutionException { if (this.jrubyVersion != null) { // preference to command line or property version return resolveJRubyCompleteArtifact(this.jrubyVersion); } else { // then take jruby from the dependencies either jruby-complete or jruby-core for (final Dependency artifact : this.project.getDependencies()) { if ((artifact.getArtifactId().equals(JRUBY_COMPLETE) || artifact.getArtifactId().equals(JRUBY_CORE)) // TODO this condition is not needed ? && !artifact.getScope().equals(Artifact.SCOPE_PROVIDED) && !artifact.getScope().equals(Artifact.SCOPE_SYSTEM)) { return resolveJRubyArtifact(this.repositorySystem .createArtifact(artifact.getGroupId(), artifact .getArtifactId(), artifact.getVersion(), artifact.getType())); } } } // finally fall back on the default version of jruby return resolveJRubyCompleteArtifact(DEFAULT_JRUBY_VERSION); } protected Artifact resolveJRubyStdlibArtifact(Artifact jruby) throws DependencyResolutionRequiredException, MojoExecutionException { final ArtifactResolutionRequest request = new ArtifactResolutionRequest(); for (final Dependency artifact : this.project.getDependencies()) { if (artifact.getArtifactId().equals(JRUBY_STDLIB) // TODO this condition is not needed ? && !artifact.getScope().equals(Artifact.SCOPE_PROVIDED) && !artifact.getScope().equals(Artifact.SCOPE_SYSTEM)) { request.setArtifact(this.repositorySystem .createArtifact(artifact.getGroupId(), artifact .getArtifactId(), artifact.getVersion(), artifact.getType())); break; } } if (request.getArtifact() == null){ request.setResolveTransitively(true); request.setArtifact(jruby); } request.setLocalRepository(this.localRepository); request.setRemoteRepositories(this.project.getRemoteArtifactRepositories()); Set set = this.repositorySystem.resolve(request).getArtifacts(); for (Artifact a: set){ if (JRUBY_STDLIB.equals(a.getArtifactId())) { return a; } } throw new MojoExecutionException("failed to resolve jruby stdlib artifact"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy