Skip to content

Commit

Permalink
Initial cut of forked compilation, currently only for sources not tes…
Browse files Browse the repository at this point in the history
…t sources. Deactivated by default
  • Loading branch information
graemerocher committed Jan 23, 2013
1 parent 274c6b7 commit d9d9a1d
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 43 deletions.
1 change: 1 addition & 0 deletions build.gradle
Expand Up @@ -133,6 +133,7 @@ subprojects { project ->
groovyOptions.fork(memoryInitialSize: '128M', memoryMaximumSize: '1G') groovyOptions.fork(memoryInitialSize: '128M', memoryMaximumSize: '1G')
groovyOptions.encoding = "UTF-8" groovyOptions.encoding = "UTF-8"
groovyOptions.useAnt = true groovyOptions.useAnt = true
groovyOptions.stacktrace = true
options.useAnt = true options.useAnt = true
} }


Expand Down
Expand Up @@ -17,9 +17,7 @@ package grails.ui.console


import grails.util.BuildSettings import grails.util.BuildSettings
import groovy.transform.CompileStatic import groovy.transform.CompileStatic
import groovy.transform.TypeCheckingMode import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProjectClassExecutor
import org.codehaus.groovy.grails.cli.fork.ExecutionContext
import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProcess


/** /**
* Forks a Groovy Swing console UI for the current application * Forks a Groovy Swing console UI for the current application
Expand All @@ -28,46 +26,24 @@ import org.codehaus.groovy.grails.cli.fork.ForkedGrailsProcess
* @since 2.3 * @since 2.3
*/ */
@CompileStatic @CompileStatic
class GrailsSwingConsole extends ForkedGrailsProcess{ class GrailsSwingConsole extends ForkedGrailsProjectClassExecutor{
ExecutionContext executionContext


GrailsSwingConsole(BuildSettings buildSettings) { GrailsSwingConsole(BuildSettings buildSettings) {
executionContext = new ExecutionContext() super(buildSettings)
executionContext.initialize(buildSettings)
} }



protected GrailsSwingConsole() {
private GrailsSwingConsole() {
executionContext = readExecutionContext()
if (executionContext == null) {
throw new IllegalStateException("Forked process created without first creating execution context and calling fork()")
}
} }


static void main(String[] args) { static void main(String[] args) {
new GrailsSwingConsole().run() new GrailsSwingConsole().run()
} }


private void run() { @Override
ExecutionContext ec = executionContext protected String getProjectClassType() { "org.codehaus.groovy.grails.project.ui.GrailsProjectConsole" }
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 @Override
ExecutionContext createExecutionContext() { void runInstance(instance) {
return executionContext ((GroovyObject)instance).invokeMethod("run", null)
} }


} }
Expand Up @@ -364,7 +364,7 @@ class BuildSettings extends AbstractBuildSettings {
/** /**
* Fork Settings. These are the default settings used to control forked mode, and what * Fork Settings. These are the default settings used to control forked mode, and what
*/ */
Map<String, Object> forkSettings = [run:false, test:false, console:false, shell:false] Map<String, Object> forkSettings = [run:false, test:false, console:false, shell:false, compile:false]


/** Implementation of the "grailsScript()" method used in Grails scripts. */ /** Implementation of the "grailsScript()" method used in Grails scripts. */
private boolean useMavenDependencyResolver private boolean useMavenDependencyResolver
Expand Down
Expand Up @@ -203,14 +203,20 @@ abstract class ForkedGrailsProcess {


@CompileStatic @CompileStatic
protected URLClassLoader createClassLoader(BuildSettings buildSettings) { protected URLClassLoader createClassLoader(BuildSettings buildSettings) {
def urls = buildSettings.runtimeDependencies.collect { File f -> f.toURI().toURL() } def classLoader = new GroovyClassLoader()
urls.addAll(buildSettings.providedDependencies.collect { File f -> f.toURI().toURL() }) for(File f in buildSettings.runtimeDependencies) {
urls.add(buildSettings.classesDir.toURI().toURL()) classLoader.addURL(f.toURI().toURL())
urls.add(buildSettings.pluginClassesDir.toURI().toURL()) }
urls.add(buildSettings.pluginBuildClassesDir.toURI().toURL()) for(File f in buildSettings.providedDependencies) {
urls.add(buildSettings.pluginProvidedClassesDir.toURI().toURL()) classLoader.addURL(f.toURI().toURL())

}
return new URLClassLoader(urls.toArray(new URL[urls.size()])) 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) { protected void setupReloading(URLClassLoader classLoader, BuildSettings buildSettings) {
Expand Down
@@ -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<String, Object>) {
this.forked = true
def map = (Map<String, Object>)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]
}
}
@@ -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
}


}
@@ -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)
}
}

Expand Up @@ -22,6 +22,7 @@ import grails.util.PluginBuildSettings
import org.codehaus.groovy.control.CompilationUnit import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.Phases 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.GrailsAwareClassLoader
import org.codehaus.groovy.grails.compiler.injection.GrailsAwareInjectionOperation import org.codehaus.groovy.grails.compiler.injection.GrailsAwareInjectionOperation
import org.codehaus.groovy.grails.plugins.GrailsPluginInfo import org.codehaus.groovy.grails.plugins.GrailsPluginInfo
Expand Down Expand Up @@ -226,8 +227,17 @@ class GrailsProjectCompiler {
* Compiles plugin and normal sources * Compiles plugin and normal sources
*/ */
void compileAll() { void compileAll() {
compilePlugins() if(buildSettings.forkSettings.compile && !Environment.isFork()) {
compile() def forkedCompiler = new ForkedGrailsCompiler(buildSettings)
def forkConfig = buildSettings.forkSettings.compile
if (forkConfig instanceof Map)
forkedCompiler.configure(forkConfig)
forkedCompiler.fork()
}
else {
compilePlugins()
compile()
}
} }


/** /**
Expand Down

0 comments on commit d9d9a1d

Please sign in to comment.