package de.saumya.mojo.jruby9.jar; import java.io.File; import java.lang.reflect.Field; import org.apache.maven.archiver.MavenArchiveConfiguration; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.archiver.UnArchiver; import de.saumya.mojo.jruby9.ArtifactHelper; import de.saumya.mojo.jruby9.ArchiveType; import de.saumya.mojo.jruby9.Versions; /** * packs a ruby application into runnable jar. * * <li>shaded jruby-complete.jar</li> * <li>shaded jruby-mains.jar</li> * <li>all declared gems and transitive gems and jars</li> * <li>all declared jars and transitive jars</li> * <li>all declared resource</li> * * the main class sets up the GEM_HOME, GEM_PATH and JARS_HOME and takes arguments * for executing jruby. any bin stubs from the gem are available via '-S' or any * script relative to jar's root can be found as the current directory is inside the jar. * * <br/> * * if there is a 'jar-bootstrap.rb' in the root of the jar, then the default main class will * execute this script and pass all the arguments to bootstrap script. * * @author christian */ @Mojo( name = "jar", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, requiresDependencyResolution = ResolutionScope.RUNTIME ) public class JarMojo extends org.apache.maven.plugin.jar.JarMojo { @Parameter( defaultValue = "runnable", property = "jruby.archive.type", required = true ) private ArchiveType type; @Parameter( defaultValue = "org.jruby.mains.JarMain", required = false ) private String mainClass; @Parameter( defaultValue = Versions.JRUBY, property = "jruby.version", required = true ) private String jrubyVersion; @Parameter( defaultValue = Versions.JRUBY_MAINS, property = "jruby.mains.version", required = true ) private String jrubyMainsVersion; @Parameter( readonly = true, defaultValue="${localRepository}" ) protected ArtifactRepository localRepository; @Component RepositorySystem system; @Component( hint = "zip" ) UnArchiver unzip; @Override public void execute() throws MojoExecutionException { switch(type) { case runnable: if (mainClass == null) { throw new MojoExecutionException( "runnable archive need mainClass configured" ); } MavenArchiveConfiguration archive = getArchive(); archive.getManifest().setMainClass(mainClass); ArtifactHelper helper = new ArtifactHelper(unzip, system, localRepository, getProject().getRemoteArtifactRepositories()); File output = new File( getProject().getBuild().getOutputDirectory()); helper.unzip(output, "org.jruby", "jruby-complete", jrubyVersion); helper.unzip(output, "org.jruby.mains", "jruby-mains", jrubyMainsVersion); case archive: break; default: throw new MojoExecutionException("can not pack archive " + type + " with jruby-jar-plugin"); } super.execute(); } private MavenArchiveConfiguration getArchive() throws MojoExecutionException { try { Field archiveField = getClass().getSuperclass().getSuperclass().getDeclaredField("archive"); archiveField.setAccessible(true); return (MavenArchiveConfiguration) archiveField.get(this); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { throw new MojoExecutionException("can not use reflection", e); } } }