Toby
Toby

Reputation: 9803

Concordion can not copy resource (all of a sudden)

Bit strange but all of a sudden (as in, my acceptance test suite was running fine and I'm busy doing some unrelated* unit tests) when I start to get failures copying resources on a test run.

Failed to copy /org/demo/foo/../../../concordion.css to target [Resource: /org/demo/foo/../../../concordion.css]
java.lang.RuntimeException: Failed to copy /org/demo/foo/../../../concordion.css to target [Resource: /org/demo/foo/../../../concordion.css]
    at org.concordion.internal.ConcordionBuilder.copyResources(ConcordionBuilder.java:354)
    at org.concordion.internal.ConcordionBuilder.build(ConcordionBuilder.java:307)
    at org.concordion.internal.FixtureRunner.<init>(FixtureRunner.java:21)
    at org.concordion.integration.junit4.ConcordionRunner.<init>(ConcordionRunner.java:62)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:78)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:66)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy1.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: /var/folders/wg/3nnv2yf90914pqpx69wmd9cc0000gn/T/concordion/org/demo/foo/../../../concordion.css (No such file or directory)
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(FileOutputStream.java:270)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
    at org.concordion.internal.FileTarget.createOutputStream(FileTarget.java:72)
    at org.concordion.internal.FileTarget.copyTo(FileTarget.java:35)
    at org.concordion.internal.ConcordionBuilder.copyResources(ConcordionBuilder.java:352)
    ... 43 more

I get this in IntelliJ IDEA and terminal running gradle.

My tests all start with something similar to this:

@RunWith(ConcordionRunner.class)
@ConcordionResources(value = { "../../../concordion.css" })
public class Index {
}

...and the .css file is where it always was (in the source tree). I checked for open handles and cleaned everything before rebuilding. Folder permissions seem fine. The /var folder in question is indeed empty.

Any ideas?

*I think

UPDATE: On Mac and Linux, if you delete the /var/folders/../concordion or /tmp/concordion (respectively), it will reproduce the problem.

Upvotes: 0

Views: 189

Answers (2)

Nigel Charman
Nigel Charman

Reputation: 753

The problem is that Concordion's FileTarget#createOutputStream(Resource) method is unable to create an OutputStream to write the resource.

Assuming your fixture is in the a.b.c package, Concordion is trying to create an OutputStream for the file "<concordion.output.dir>/a/b/c/../../../concordion.css" (where <concordion.output.dir> is the concordion output directory). If the "<concordion.output.dir>/a/b/c/" folder does not already exist this fails - it seems that Java does not automatically "normalize" the path to remove ".."s.

The solution will be to normalize the path (probably using Path.normalize()).

To resolve, you can either update to the 2.2.1 release which should be available soon, or use absolute paths (eg. @ConcordionResources("/concordion.css")).

Upvotes: 0

Tim Wright
Tim Wright

Reputation: 109

Have you considered filename or directory capitalisation? Linux is is strict whereas Mac is odd with filename capitalisation.

Tim

Upvotes: -1

Related Questions