Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 1.3.5
-
Component/s: Project infrastructure
-
Labels:None
-
Environment:Ubuntu 10.10, Grails 1.3.5
Description
We have created a way of managing our 15+ environments using different configuration files stored under a directory called ./environment
The default configuration file ./grails-app/conf/Config.groovy pulls in these files as follows:
{{
environments {
development
{ loader.load(testCommon, 'test/Development') }perftest
{ loader.load(testCommon, 'test/PerfTest') }selenium
{ loader.load(testCommon, 'test/Selenium') } ...
}
}}
Where loader is an instance of our own class EnvironmentConfigLoader which we import at the top of the Config.groovy file.
If a fresh checkout of the project is done, hence the ~/.grails/projects/1.3.5/myprojectname is newly created, running 'grails run-war' or 'grails compile' does not work, with the following exception:
{{
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script12906073437641435994217.groovy: 4: unable to resolve class xxx.yyy.EnvironmentConfigLoader
@ line 4, column 1.
import xxx.yyy.EnvironmentConfigLoader
^
}}
We believe this is because the /.grails/projects/1.3.5/myprojectname/classes directory has not yet been created, and this is indeed the case after the first grails compile or grails run-war call - the directory does not exist, since the compilation of the files in /.grails/projects/1.3.5/myprojectname/scriptCache could not complete.
It seems logical that the files in the application's classpath (i.e. ./src/*) should be compiled first, meaning that scripts, config etc. can then use classes on the application's classpath.
We have noticed that the same issue exists for plugins, whereby our './scripts/Events.groovy' script cannot import classes provided by plugins UNTIL at least one run-app has been done.
-
Hide
- grails6970-bug-report-24112010.zip
- 24/Nov/10 10:59 AM
- 69 kB
- Antony Jones
-
- grails-app/conf/BootStrap.groovy 0.2 kB
- grails-app/conf/BuildConfig.groovy 1 kB
- grails-app/conf/Config.groovy 4 kB
- grails-app/conf/DataSource.groovy 0.8 kB
- grails-app/conf/UrlMappings.groovy 0.2 kB
- grails-app/conf/spring/resources.groovy 0.0 kB
- grails-app/i18n/messages.properties 3 kB
- grails-app/i18n/messages_da.properties 3 kB
- grails-app/i18n/messages_de.properties 4 kB
- grails-app/i18n/messages_es.properties 3 kB
- grails-app/i18n/messages_fr.properties 2 kB
- grails-app/i18n/messages_it.properties 2 kB
- grails-app/i18n/messages_ja.properties 2 kB
- grails-app/i18n/messages_nl.properties 3 kB
- grails-app/.../messages_pt_BR.properties 3 kB
- grails-app/.../messages_pt_PT.properties 3 kB
- grails-app/i18n/messages_ru.properties 4 kB
- grails-app/i18n/messages_th.properties 5 kB
- grails-app/.../messages_zh_CN.properties 2 kB
- grails-app/utils/.../Thing.groovy 0.1 kB
- grails-app/views/error.gsp 2 kB
- grails-app/views/index.gsp 4 kB
- grails-app/views/layouts/main.gsp 0.7 kB
- test/jsunit/app/css/jsUnitStyle.css 2 kB
- test/jsunit/app/emptyPage.html 0.3 kB
- test/jsunit/app/jsUnitCore.js 30 kB
- test/jsunit/app/jsUnitTestManager.js 26 kB
- test/jsunit/app/jsUnitTracer.js 4 kB
- test/jsunit/app/main-counts-errors.html 0.3 kB
- test/jsunit/.../main-counts-failures.html 0.4 kB
Activity
- All
- Comments
- Work Log
- History
- Activity
- Git Commits
It turns out that there WAS a bug in one of our plugins, but there is also an issue in the Grails Upgrade.groovy script.
The code in question is as follows
{{
// if Config.groovy exists and it does not contain values for
// grails.views.default.codec or grails.views.gsp.encoding then
// add reasonable defaults for them
def configFile = new File(baseFile, '/grails-app/conf/Config.groovy')
if (configFile.exists()) {
def configSlurper = new ConfigSlurper()
def configObject = configSlurper.parse(configFile.toURI().toURL())
def defaultCodec = configObject.grails.views.default.codec
def gspEncoding = configObject.grails.views.gsp.encoding
if (!defaultCodec || !gspEncoding) {
configFile.withWriterAppend
}
}
}}
When this code executes, it attemps to load the Config.groovy file and slurp it, however when it encounters an import statement which imports one of the classes in the project, it falls over, as these have not yet been compiled into .grails/projects/1.3.5/yourprojectname/classes
The error then shows up as follows, and the upgrade fails:
{{
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script1290617258296782601755.groovy: 4: unable to resolve class xxx.util.EnvironmentConfigLoader
@ line 4, column 1.
import xxx.util.EnvironmentConfigLoader
^
1 error
at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:391)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:427)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:415)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.executeTargets(Gant.groovy:590)
at gant.Gant.executeTargets(Gant.groovy:589)
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script1290617258296782601755.groovy: 4: unable to resolve class xxx.util.EnvironmentConfigLoader
@ line 4, column 1.
import xxx.util.EnvironmentConfigLoader
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:296)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:829)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:511)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:487)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:464)
at Upgrade$_run_closure1_closure3.doCall(Upgrade.groovy:153)
at Upgrade$_run_closure1_closure3.doCall(Upgrade.groovy)
at Upgrade$_run_closure1.doCall(Upgrade.groovy:78)
at Upgrade$_run_closure2.doCall(Upgrade.groovy:219)
at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
... 10 more
— Nested Exception —
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script1290617258296782601755.groovy: 4: unable to resolve class xxx.util.EnvironmentConfigLoader
@ line 4, column 1.
import xxx.util.EnvironmentConfigLoader
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:296)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:829)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:511)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:487)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:464)
at Upgrade$_run_closure1_closure3.doCall(Upgrade.groovy:153)
at Upgrade$_run_closure1_closure3.doCall(Upgrade.groovy)
at Upgrade$_run_closure1.doCall(Upgrade.groovy:78)
at Upgrade$_run_closure2.doCall(Upgrade.groovy:219)
at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:427)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:415)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.executeTargets(Gant.groovy:590)
at gant.Gant.executeTargets(Gant.groovy:589)
Error executing script Upgrade: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script1290617258296782601755.groovy: 4: unable to resolve class xxx.util.EnvironmentConfigLoader
@ line 4, column 1.
import xxx.util.EnvironmentConfigLoader
^
1 error
}}
Attaching an example.
Extract the ZIP, and run:
'grails upgrade'
The upgrade will immediately fail with error cannot resolve class 'import my.seemingly.unresolvable.Thing'.
If you run grails compile it will begin to work, you can quickly break it again by deleting ~/.grails/1.3.5/projects/yourprojectname
Turns out one of our plugins (written by an external company) was causing the issue by trying to read the Config file as part of its build process.
There is potentially still an issue in that the plugin cannot configuration at bootstrap time, but if we encounter this in fixing the plugin, we will raise it at a later stage.