package org.grails.maven.plugin.tools;
import org.apache.maven.plugin.MojoExecutionException;
import org.grails.launcher.GrailsLauncher;
import org.grails.launcher.RootLoader;
import java.io.File;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @author Andrew Potter (ddcapotter)
*/
public abstract class AbstractGrailsRuntime {
public AbstractGrailsRuntime(ExecutionContext context) {
this.executionContext = context;
}
public abstract void run() throws MojoExecutionException;
protected ExecutionContext executionContext;
public static GrailsLauncher createGrailsLauncher(ExecutionContext ec) {
URL[] urls = generateBuildPath(ec.getBuildDependencies());
final RootLoader rootLoader = new RootLoader(urls, ClassLoader.getSystemClassLoader());
System.setProperty("grails.console.enable.terminal", "false");
System.setProperty("grails.console.enable.interactive", "false");
List<File> compileDependencies = ec.getCompileDependencies();
try {
addLoggingJarsToRootLoader(rootLoader, compileDependencies);
} catch (Exception e) {
throw new RuntimeException(e);
}
final GrailsLauncher launcher = new GrailsLauncher(rootLoader, null, ec.getBaseDir().getAbsolutePath());
launcher.setPlainOutput(true);
launcher.setDependenciesExternallyConfigured(true);
launcher.setProvidedDependencies(ec.getProvidedDependencies());
launcher.setCompileDependencies(compileDependencies);
launcher.setTestDependencies(ec.getTestDependencies());
launcher.setRuntimeDependencies(ec.getRuntimeDependencies());
launcher.setGrailsWorkDir(ec.getGrailsWorkDir());
launcher.setProjectWorkDir(ec.getProjectWorkDir());
launcher.setClassesDir(ec.getClassesDir());
launcher.setTestClassesDir(ec.getTestClassesDir());
launcher.setResourcesDir(ec.getResourcesDir());
launcher.setProjectPluginsDir(ec.getProjectPluginsDir());
launcher.setBuildDependencies(ec.getBuildDependencies());
return launcher;
}
public static void addLoggingJarsToRootLoader(RootLoader rootLoader, List<File> compileDependencies) throws MalformedURLException, ClassNotFoundException {
List<File> loggingBootstrapJars = new ArrayList<File>();
for (File file : compileDependencies) {
String name = file.getName();
if(name.contains("slf4j") || name.contains("log4j") || name.contains("spring-core") || name.contains("logback")) {
loggingBootstrapJars.add(file);
}
}
if(!loggingBootstrapJars.isEmpty()) {
for (File loggingBootstrapJar : loggingBootstrapJars) {
rootLoader.addURL(loggingBootstrapJar.toURI().toURL());
}
Class cls = rootLoader.loadClass("org.springframework.util.Log4jConfigurer");
try {
invokeStaticMethod(cls, "initLogging", new Object[]{"classpath:grails-maven/log4j.properties"});
} catch (Throwable e) {
// ignore
}
}
}
/**
* Invokes the named method on a target object using reflection.
* The method signature is determined by the classes of each argument.
* @param target The object to call the method on.
* @param name The name of the method to call.
* @param args The arguments to pass to the method (may be an empty array).
* @return The value returned by the method.
*/
private static Object invokeStaticMethod(Class target, String name, Object[] args) {
Class<?>[] argTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = args[i].getClass();
}
try {
return target.getMethod(name, argTypes).invoke(target, args);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
protected static void fatalError(Throwable e) {
System.out.println();
System.out.println("Fatal error forking Grails JVM: " + e.getMessage());
e.printStackTrace(System.out);
System.out.flush();
System.exit(1);
}
protected static URL[] generateBuildPath(List<File> systemDependencies) {
List<URL> urls = new ArrayList<URL>();
for (File systemDependency : systemDependencies) {
try {
urls.add(systemDependency.toURI().toURL());
} catch (MalformedURLException e) {
// ignore
}
}
return urls.toArray(new URL[urls.size()]);
}
public static class ExecutionContext implements Serializable {
private List<File> compileDependencies;
private List<File> runtimeDependencies;
private List<File> buildDependencies;
private List<File> providedDependencies;
private List<File> testDependencies;
private List forkedVmArgs;
private File grailsWorkDir;
private File projectWorkDir;
private File classesDir;
private File testClassesDir;
private File resourcesDir;
private File projectPluginsDir;
private File baseDir;
private File dependencyFileLocation;
private String scriptName;
private String env;
private String args;
private String grailsBuildListener;
public String getScriptName() {
return scriptName;
}
public void setScriptName(String scriptName) {
this.scriptName = scriptName;
}
public String getEnv() {
return env;
}
public void setEnv(String env) {
this.env = env;
}
public String getArgs() {
return args;
}
public void setArgs(String args) {
this.args = args;
}
public List<String> getForkedVmArgs() {
return forkedVmArgs;
}
public void setForkedVmArgs(List<String> forkedVmArgs) {
this.forkedVmArgs = forkedVmArgs;
}
public File getBaseDir() {
return baseDir;
}
public void setBaseDir(File baseDir) {
this.baseDir = baseDir;
}
public List<File> getCompileDependencies() {
return compileDependencies;
}
public void setCompileDependencies(List<File> compileDependencies) {
this.compileDependencies = compileDependencies;
}
public List<File> getRuntimeDependencies() {
return runtimeDependencies;
}
public void setRuntimeDependencies(List<File> runtimeDependencies) {
this.runtimeDependencies = runtimeDependencies;
}
public List<File> getBuildDependencies() {
return buildDependencies;
}
public void setBuildDependencies(List<File> buildDependencies) {
this.buildDependencies = buildDependencies;
}
public List<File> getProvidedDependencies() {
return providedDependencies;
}
public void setProvidedDependencies(List<File> providedDependencies) {
this.providedDependencies = providedDependencies;
}
public List<File> getTestDependencies() {
return testDependencies;
}
public void setTestDependencies(List<File> testDependencies) {
this.testDependencies = testDependencies;
}
public File getGrailsWorkDir() {
return grailsWorkDir;
}
public void setGrailsWorkDir(File grailsWorkDir) {
this.grailsWorkDir = grailsWorkDir;
}
public File getProjectWorkDir() {
return projectWorkDir;
}
public void setProjectWorkDir(File projectWorkDir) {
this.projectWorkDir = projectWorkDir;
}
public File getClassesDir() {
return classesDir;
}
public void setClassesDir(File classesDir) {
this.classesDir = classesDir;
}
public File getTestClassesDir() {
return testClassesDir;
}
public void setTestClassesDir(File testClassesDir) {
this.testClassesDir = testClassesDir;
}
public File getResourcesDir() {
return resourcesDir;
}
public void setResourcesDir(File resourcesDir) {
this.resourcesDir = resourcesDir;
}
public File getProjectPluginsDir() {
return projectPluginsDir;
}
public void setProjectPluginsDir(File projectPluginsDir) {
this.projectPluginsDir = projectPluginsDir;
}
public File getDependencyFileLocation() {
return dependencyFileLocation;
}
public void setDependencyFileLocation(File dependencyFile) {
this.dependencyFileLocation = dependencyFile;
}
public String getGrailsBuildListener() {
return grailsBuildListener;
}
public void setGrailsBuildListener(String buildListener) {
this.grailsBuildListener = buildListener;
}
}
}