diff --git a/build.gradle b/build.gradle index 229c1c8275a..2de123910d2 100644 --- a/build.gradle +++ b/build.gradle @@ -133,6 +133,7 @@ subprojects { project -> groovyOptions.fork(memoryInitialSize: '128M', memoryMaximumSize: '1G') groovyOptions.encoding = "UTF-8" groovyOptions.useAnt = true + groovyOptions.stacktrace = true options.useAnt = true } diff --git a/grails-bootstrap/src/main/groovy/grails/ui/console/GrailsSwingConsole.groovy b/grails-bootstrap/src/main/groovy/grails/ui/console/GrailsSwingConsole.groovy index 17d8cc2817c..242a6e452bb 100644 --- a/grails-bootstrap/src/main/groovy/grails/ui/console/GrailsSwingConsole.groovy +++ b/grails-bootstrap/src/main/groovy/grails/ui/console/GrailsSwingConsole.groovy @@ -17,9 +17,7 @@ package grails.ui.console import grails.util.BuildSettings import groovy.transform.CompileStatic -import groovy.transform.TypeCheckingMode -import org.codehaus.groovy.grails.cli.fork.ExecutionContext -import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProcess +import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProjectClassExecutor /** * Forks a Groovy Swing console UI for the current application @@ -28,46 +26,24 @@ import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProcess * @since 2.3 */ @CompileStatic -class GrailsSwingConsole extends ForkedGrailsProcess{ - ExecutionContext executionContext +class GrailsSwingConsole extends ForkedGrailsProjectClassExecutor{ GrailsSwingConsole(BuildSettings buildSettings) { - executionContext = new ExecutionContext() - executionContext.initialize(buildSettings) + super(buildSettings) } - - private GrailsSwingConsole() { - executionContext = readExecutionContext() - if (executionContext == null) { - throw new IllegalStateException("Forked process created without first creating execution context and calling fork()") - } + protected GrailsSwingConsole() { } static void main(String[] args) { new GrailsSwingConsole().run() } - private void run() { - ExecutionContext ec = executionContext - BuildSettings buildSettings = initializeBuildSettings(ec) - URLClassLoader classLoader = initializeClassLoader(buildSettings) - initializeLogging(ec.grailsHome,classLoader) - Thread.currentThread().setContextClassLoader(classLoader) - - final projectConsole = classLoader.loadClass("org.codehaus.groovy.grails.project.ui.GrailsProjectConsole").newInstance(buildSettings) - - runConsole(projectConsole) - } - - void runConsole(def console) { - ((GroovyObject)console).invokeMethod("run", null) - } + @Override + protected String getProjectClassType() { "org.codehaus.groovy.grails.project.ui.GrailsProjectConsole" } @Override - ExecutionContext createExecutionContext() { - return executionContext + void runInstance(instance) { + ((GroovyObject)instance).invokeMethod("run", null) } - - } diff --git a/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy b/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy index 74d84078c1c..79480e40e37 100644 --- a/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy +++ b/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy @@ -364,7 +364,7 @@ class BuildSettings extends AbstractBuildSettings { /** * Fork Settings. These are the default settings used to control forked mode, and what */ - Map forkSettings = [run:false, test:false, console:false, shell:false] + Map forkSettings = [run:false, test:false, console:false, shell:false, compile:false] /** Implementation of the "grailsScript()" method used in Grails scripts. */ private boolean useMavenDependencyResolver diff --git a/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcess.groovy b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcess.groovy index 06427a0346f..a420ec5f0a7 100644 --- a/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcess.groovy +++ b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcess.groovy @@ -203,14 +203,20 @@ abstract class ForkedGrailsProcess { @CompileStatic protected URLClassLoader createClassLoader(BuildSettings buildSettings) { - def urls = buildSettings.runtimeDependencies.collect { File f -> f.toURI().toURL() } - urls.addAll(buildSettings.providedDependencies.collect { File f -> f.toURI().toURL() }) - urls.add(buildSettings.classesDir.toURI().toURL()) - urls.add(buildSettings.pluginClassesDir.toURI().toURL()) - urls.add(buildSettings.pluginBuildClassesDir.toURI().toURL()) - urls.add(buildSettings.pluginProvidedClassesDir.toURI().toURL()) - - return new URLClassLoader(urls.toArray(new URL[urls.size()])) + def classLoader = new GroovyClassLoader() + for(File f in buildSettings.runtimeDependencies) { + classLoader.addURL(f.toURI().toURL()) + } + for(File f in buildSettings.providedDependencies) { + classLoader.addURL(f.toURI().toURL()) + } + classLoader.addURL(buildSettings.classesDir.toURI().toURL()) + classLoader.addURL(buildSettings.pluginClassesDir.toURI().toURL()) + classLoader.addURL(buildSettings.pluginBuildClassesDir.toURI().toURL()) + classLoader.addURL(buildSettings.pluginProvidedClassesDir.toURI().toURL()) + + + return classLoader } protected void setupReloading(URLClassLoader classLoader, BuildSettings buildSettings) { diff --git a/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcessConfig.groovy b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcessConfig.groovy new file mode 100644 index 00000000000..84cc869c2e2 --- /dev/null +++ b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcessConfig.groovy @@ -0,0 +1,65 @@ +/* + * Copyright 2012 SpringSource + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.codehaus.groovy.grails.cli.fork + +import groovy.transform.CompileStatic + +/** + * Configuration for a forked process + * + * @author Graeme Rocher + * @since 2.3 + */ +@CompileStatic +class ForkedGrailsProcessConfig { + + ForkedGrailsProcessConfig(config) { + if (config instanceof Map) { + this.forked = true + def map = (Map)config + + if (map.maxMemory) { + maxMemory = map.maxMemory.toString().toInteger() + } + if (map.minMemory) { + minMemory = map.minMemory.toString().toInteger() + } + if (map.maxPerm) { + maxPerm = map.maxPerm.toString().toInteger() + } + if (map.debug) { + debug = true + } + + } + else if (config) { + this.forked = true + } + } + + ForkedGrailsProcessConfig() { + } + + Integer maxMemory = 512 + Integer minMemory = 64 + boolean debug = false + Integer maxPerm = 256 + boolean forked = false + + Map asMap() { + [maxMemory:maxMemory, minMemory:minMemory, debug:debug, maxPerm:maxPerm] + } +} diff --git a/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProjectClassExecutor.groovy b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProjectClassExecutor.groovy new file mode 100644 index 00000000000..49587bcb0c3 --- /dev/null +++ b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProjectClassExecutor.groovy @@ -0,0 +1,72 @@ +/* + * Copyright 2012 SpringSource + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.codehaus.groovy.grails.cli.fork + +import grails.util.BuildSettings +import groovy.transform.CompileStatic + +/** + * Base class that deals with the setup logic needed in order to run a Grails build system component (GrailsProjectCompiler, GrailsProjectLoader, GrailsProjectRunner etc.) in a forked process + * + * @author Graeme Rocher + * @since 2.3 + */ +@CompileStatic +abstract class ForkedGrailsProjectClassExecutor extends ForkedGrailsProcess{ + ExecutionContext executionContext + + ForkedGrailsProjectClassExecutor(BuildSettings buildSettings) { + executionContext = new ExecutionContext() + executionContext.initialize(buildSettings) + } + + + protected ForkedGrailsProjectClassExecutor() { + executionContext = readExecutionContext() + if (executionContext == null) { + throw new IllegalStateException("Forked process created without first creating execution context and calling fork()") + } + } + + + protected final void run() { + ExecutionContext ec = executionContext + BuildSettings buildSettings = initializeBuildSettings(ec) + URLClassLoader classLoader = initializeClassLoader(buildSettings) + initializeLogging(ec.grailsHome,classLoader) + Thread.currentThread().setContextClassLoader(classLoader) + + final projectComponentClass = classLoader.loadClass(getProjectClassType()) + final projectClassInstance = createInstance(projectComponentClass, buildSettings) + + runInstance(projectClassInstance) + } + + protected Object createInstance(Class projectComponentClass, BuildSettings buildSettings) { + projectComponentClass.newInstance(buildSettings) + } + + protected abstract String getProjectClassType() + + abstract void runInstance(def instance) + + @Override + ExecutionContext createExecutionContext() { + return executionContext + } + + +} diff --git a/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/compile/ForkedGrailsCompiler.groovy b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/compile/ForkedGrailsCompiler.groovy new file mode 100644 index 00000000000..4adb917a7f7 --- /dev/null +++ b/grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/compile/ForkedGrailsCompiler.groovy @@ -0,0 +1,66 @@ +/* + * Copyright 2012 SpringSource + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.codehaus.groovy.grails.cli.fork.compile + +import grails.build.logging.GrailsConsole +import grails.util.BuildSettings +import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProjectClassExecutor +import org.codehaus.groovy.grails.plugins.GrailsPluginUtils + +/** + * Forked implementation of Grails project compiler + * + * @author Graeme Rocher + * @since 2.3 + */ +class ForkedGrailsCompiler extends ForkedGrailsProjectClassExecutor{ + + ForkedGrailsCompiler(BuildSettings buildSettings) { + super(buildSettings) + this.reloading = false + } + + protected ForkedGrailsCompiler() { + } + + static void main(String[] args) { + try { + new ForkedGrailsCompiler().run() + System.exit(0) + } catch (Throwable e) { + GrailsConsole.getInstance().error("Error running forked compilation: " + e.getMessage(), e) + System.exit(1) + } + + } + + @Override + protected String getProjectClassType() { + return "org.codehaus.groovy.grails.compiler.GrailsProjectCompiler" + } + + @Override + protected Object createInstance(Class projectComponentClass, BuildSettings buildSettings) { + projectComponentClass.newInstance(GrailsPluginUtils.getPluginBuildSettings()) + } + + @Override + void runInstance(instance) { + ((GroovyObject)instance).invokeMethod("configureClasspath", null) + ((GroovyObject)instance).invokeMethod("compileAll", null) + } +} + diff --git a/grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/GrailsProjectCompiler.groovy b/grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/GrailsProjectCompiler.groovy index f693fe9bfbc..9ebfbb1f2fd 100644 --- a/grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/GrailsProjectCompiler.groovy +++ b/grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/GrailsProjectCompiler.groovy @@ -22,6 +22,7 @@ import grails.util.PluginBuildSettings import org.codehaus.groovy.control.CompilationUnit import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.Phases +import org.codehaus.groovy.grails.cli.fork.compile.ForkedGrailsCompiler import org.codehaus.groovy.grails.compiler.injection.GrailsAwareClassLoader import org.codehaus.groovy.grails.compiler.injection.GrailsAwareInjectionOperation import org.codehaus.groovy.grails.plugins.GrailsPluginInfo @@ -226,8 +227,17 @@ class GrailsProjectCompiler { * Compiles plugin and normal sources */ void compileAll() { - compilePlugins() - compile() + if(buildSettings.forkSettings.compile && !Environment.isFork()) { + def forkedCompiler = new ForkedGrailsCompiler(buildSettings) + def forkConfig = buildSettings.forkSettings.compile + if (forkConfig instanceof Map) + forkedCompiler.configure(forkConfig) + forkedCompiler.fork() + } + else { + compilePlugins() + compile() + } } /**