Details
Description
Lets say we modify the testValidationTurnedOnThrowsExceptionForUnknownAttributes() test case to have an error in it like so. (Missing Import for NullNodeBuilderDecorationDelegate())
public void testValidationTurnedOnThrowsExceptionForUnknownAttributes() {
DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
Reader script = new StringReader(
"import org.nanocontainer.script.groovy.*\n" +
"builder = new CustomGroovyNodeBuilder(new NullNodeBuilderDecorationDelegate(), CustomGroovyNodeBuilder.PERFORM_ATTRIBUTE_VALIDATION)\n" +
"nano = builder.container
");
try
{ buildContainer(script, parent, ASSEMBLY_SCOPE); fail("CustomGroovyNodeBuilder with validation should have thrown NanoContainerMarkupException"); } catch(GroovyCompilationException ex) { //Weed out the groovy compilation exceptions throw ex; } catch (NanoContainerMarkupException ex) { //a-ok }}
Then we get a rather unhelpful error message from the GroovyCompilationException:
public void testValidationTurnedOnThrowsExceptionForUnknownAttributes() {
DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
Reader script = new StringReader(
"import org.nanocontainer.script.groovy.*\n" +
"builder = new CustomGroovyNodeBuilder(new NullNodeBuilderDecorationDelegate(), CustomGroovyNodeBuilder.PERFORM_ATTRIBUTE_VALIDATION)\n" +
"nano = builder.container {\n" + " component(key:'a', instance:'apple', badAttribute:'foo')\n" + "}");
try { buildContainer(script, parent, ASSEMBLY_SCOPE); fail("CustomGroovyNodeBuilder with validation should have thrown NanoContainerMarkupException"); }
catch(GroovyCompilationException ex)
{ //Weed out the groovy compilation exceptions throw ex; }catch (NanoContainerMarkupException ex)
{ //a-ok }}
However, if I go into GroovyContainerBuilder.createGroovyScript() and modify it so I printStackTrace() on the compilation exception like so:
private void createGroovyScript() {
try
catch (CompilationFailedException e)
{ e.printStackTrace(); throw new GroovyCompilationException("Compilation Failed '" + e.getMessage() + "'", e); }catch (IOException e)
{ throw new NanoContainerMarkupException(e); }}
Then we get the nice error:
General error during class generation: No such class: NullNodeBuilderDecorationDelegate in constructor call for class: nanocontainer. At [2:39] nanocontainer.groovy
1 Error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:325)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:879)
at org.codehaus.groovy.control.CompilationUnit.classgen(CompilationUnit.java:564)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:469)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:246)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:209)
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createGroovyScript(GroovyContainerBuilder.java:92)
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createContainerFromScript(GroovyContainerBuilder.java:52)
at org.nanocontainer.script.ScriptedContainerBuilder.createContainer(ScriptedContainerBuilder.java:60)
at org.nanocontainer.integrationkit.LifecycleContainerBuilder.buildContainer(LifecycleContainerBuilder.java:26)
at org.nanocontainer.script.AbstractScriptedContainerBuilderTestCase.buildContainer(AbstractScriptedContainerBuilderTestCase.java:27)
at org.nanocontainer.script.groovy.CustomGroovyNodeBuilderTestCase.buildContainer(CustomGroovyNodeBuilderTestCase.java:604)
at org.nanocontainer.script.groovy.CustomGroovyNodeBuilderTestCase.testValidationTurnedOnThrowsExceptionForUnknownAttributes(CustomGroovyNodeBuilderTestCase.java:575)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at org.jmock.core.VerifyingTestCase.runBare(Unknown Source)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at com.borland.jbuilder.unittest.JBTestRunner.a(Unknown Source)
at com.borland.jbuilder.unittest.JBTestRunner.initiateTest(Unknown Source)
at com.borland.jbuilder.unittest.JBTestRunner.main(Unknown Source)
I've looked into it a bit and it appears there's no way for the Standard printStackTrace() to get at the cause because GroovyCompilationException's constructor is:
public GroovyCompilationException(String message, CompilationFailedException e)
{ super(message); this.compilationFailedException = e; }So the compilation exception never gets passed up to the PicoException as a cause. I see special code for extracting the errors in GroovyCompilationException so I'm not sure what's expected here. For the record, if I modify the constructor to:
public GroovyCompilationException(String message, CompilationFailedException e)
{ super(message,e); this.compilationFailedException = e; }Then GroovyCompilationException.printStackTrace() gives me what I would expect:
org.nanocontainer.script.groovy.GroovyCompilationException: Compilation Failed 'startup failed'
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createGroovyScript(GroovyContainerBuilder.java:95)
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createContainerFromScript(GroovyContainerBuilder.java:52)
at org.nanocontainer.script.ScriptedContainerBuilder.createContainer(ScriptedContainerBuilder.java:60)
at org.nanocontainer.integrationkit.LifecycleContainerBuilder.buildContainer(LifecycleContainerBuilder.java:26)
at org.nanocontainer.script.AbstractScriptedContainerBuilderTestCase.buildContainer(AbstractScriptedContainerBuilderTestCase.java:27)
at org.nanocontainer.script.groovy.CustomGroovyNodeBuilderTestCase.buildContainer(CustomGroovyNodeBuilderTestCase.java:610)
at org.nanocontainer.script.groovy.CustomGroovyNodeBuilderTestCase.testValidationTurnedOnThrowsExceptionForUnknownAttributes(CustomGroovyNodeBuilderTestCase.java:575)
...(Click for full stack trace)...
at org.jmock.core.VerifyingTestCase.runBare(Unknown Source)
...
Caused by: General error during class generation: No such class: NullNodeBuilderDecorationDelegate in constructor call for class: nanocontainer. At [2:39] nanocontainer.groovy
1 Error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:325)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:879)
at org.codehaus.groovy.control.CompilationUnit.classgen(CompilationUnit.java:564)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:469)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:246)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:209)
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createGroovyScript(GroovyContainerBuilder.java:92)
... 21 more
Caused by:
General error during class generation: No such class: NullNodeBuilderDecorationDelegate in constructor call for class: nanocontainer. At [2:39] nanocontainer.groovy
1 Error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:325)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:879)
at org.codehaus.groovy.control.CompilationUnit.classgen(CompilationUnit.java:564)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:469)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:246)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:209)
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createGroovyScript(GroovyContainerBuilder.java:92)
at org.nanocontainer.script.groovy.GroovyContainerBuilder.createContainerFromScript(GroovyContainerBuilder.java:52)
at org.nanocontainer.script.ScriptedContainerBuilder.createContainer(ScriptedContainerBuilder.java:60)
at org.nanocontainer.integrationkit.LifecycleContainerBuilder.buildContainer(LifecycleContainerBuilder.java:26)
at org.nanocontainer.script.AbstractScriptedContainerBuilderTestCase.buildContainer(AbstractScriptedContainerBuilderTestCase.java:27)
at org.nanocontainer.script.groovy.CustomGroovyNodeBuilderTestCase.buildContainer(CustomGroovyNodeBuilderTestCase.java:610)
at org.nanocontainer.script.groovy.CustomGroovyNodeBuilderTestCase.testValidationTurnedOnThrowsExceptionForUnknownAttributes(CustomGroovyNodeBuilderTestCase.java:575)
...
at org.jmock.core.VerifyingTestCase.runBare(Unknown Source)
...
But that appears to go against something already set there in the code.
Any thoughts guys?
Activity
Field | Original Value | New Value |
---|---|---|
Fix Version/s | 1.0 [ 10148 ] | |
Resolution | Fixed [ 1 ] | |
Assignee | Michael Rimov [ rimovm ] | |
Status | Open [ 1 ] | Resolved [ 5 ] |
The CompilationFailedException used to originally encode the error information
in a different way - it changed somewhere between jsr-01 and jsr-03.
But yes - I think adding the exception to the super constructor is the right thing to do,
and certainly does no harm!
Why do you say it goes against something in the code?
The idea of the getMessage() is to put into a human-readable form the
errors contained in the exception without having to do a printStackTrace().