Fatal Error: Resource for javac is missing with ant taskdef (new in version 1.0-rc-1)

We’ve had great experience with Gradle thus far. Thanks for all the hard work.

When upgrading to 1.0-rc-1 (from 1.0-milestone-9) we started seeing the following error:

java.lang.Error: Fatal Error: Resource for javac is missing

java.util.MissingResourceException: Can’t find bundle for base name com.sun.tools.javac.resources.javac, locale en_US

I think I tracked the issue down to an ant taskdef in a task in one of the sub-projects. When that task does not run, the error does not occur.

I’ve reproduced with a setup that has the following sub-projects: JavaProj - Java project with a few dependencies XjcProj - Groovy project with a task that uses com.sun.tools.xjc.XJCTask to generate source files from XSD TestProj - Java project that depends on XjcProject

Here’s the definition of the task that runs XJC…

task generateSrcFromXsd() {
  description = 'Generates java source from XSD using XJC compiler'
  inputs.dir xsdDir
  outputs.dir generatedSrcDir
  doLast {
   def jaxbClasspath = configurations.jaxb.copy()
   jaxbClasspath.transitive = true
   ant.taskdef name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: jaxbClasspath.asPath
   ant.mkdir dir: generatedSrcDir
   ant.xjc extension: true, schema: "$xsdDir/Thing.xsd", destdir: generatedSrcDir, package: 'xsdproj.generated'
  }
 }

Here is the output when the error occurs…

:JavaProj:compileJava
:JavaProj:processResources UP-TO-DATE
:JavaProj:classes
:JavaProj:jar
:JavaProj:assemble
:XjcProj:generateSrcFromXsd
:XjcProj:compileJava UP-TO-DATE
:XjcProj:compileGroovy
:XjcProj:processResources UP-TO-DATE
:XjcProj:classes
:XjcProj:jar
:TestProj:compileJava
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':TestProj:compileJava'.
> Fatal Error: Resource for javac is missing
  * Try:
Run with --info or --debug option to get more log output.
  * Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':TestProj:compileJava'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:68)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:34)
        at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter$1.run(CacheLockHandlingTaskExecuter.java:34)
        at org.gradle.cache.internal.DefaultCacheAccess$2.create(DefaultCacheAccess.java:200)
        at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:172)
        at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:198)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:111)
        at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.longRunningOperation(DefaultTaskArtifactStateCacheAccess.java:83)
        at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter.execute(CacheLockHandlingTaskExecuter.java:32)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:41)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:42)
        at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:247)
        at org.gradle.execution.DefaultTaskGraphExecuter.executeTask(DefaultTaskGraphExecuter.java:192)
        at org.gradle.execution.DefaultTaskGraphExecuter.doExecute(DefaultTaskGraphExecuter.java:177)
        at org.gradle.execution.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:83)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:36)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
        at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
        at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter$1.run(TaskCacheLockHandlingBuildExecuter.java:31)
        at org.gradle.cache.internal.DefaultCacheAccess$1.create(DefaultCacheAccess.java:111)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:126)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:109)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:103)
        at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.useCache(DefaultTaskArtifactStateCacheAccess.java:79)
        at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter.execute(TaskCacheLockHandlingBuildExecuter.java:29)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
        at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:155)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:110)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:78)
        at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:38)
        at org.gradle.launcher.daemon.protocol.Build.run(Build.java:68)
        at org.gradle.launcher.daemon.protocol.Build.run(Build.java:64)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:45)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:45)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:28)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ReturnResult.execute(ReturnResult.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$4.call(ForwardClientInput.java:116)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$4.call(ForwardClientInput.java:114)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:114)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:61)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.doBuild(StartBuildOrRespondWithBusy.java:49)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.HandleStop.execute(HandleStop.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.CatchAndForwardDaemonFailure.execute(CatchAndForwardDaemonFailure.java:32)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.HandleClientDisconnectBeforeSendingCommand.execute(HandleClientDisconnectBeforeSendingCommand.java:21)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StopConnectionAfterExecution.execute(StopConnectionAfterExecution.java:27)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.DefaultDaemonCommandExecuter.executeCommand(DefaultDaemonCommandExecuter.java:55)
        at org.gradle.launcher.daemon.server.Daemon$1$1.run(Daemon.java:123)
        at org.gradle.messaging.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
Caused by: java.lang.Error: Fatal Error: Resource for javac is missing
        at com.sun.tools.javac.main.Main.getLocalizedString(Main.java:451)
        at com.sun.tools.javac.main.Main.bugMessage(Main.java:400)
        at com.sun.tools.javac.main.Main.compile(Main.java:387)
        at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:115)
        at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:40)
        at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:33)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:95)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:48)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:34)
        at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:29)
        at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:20)
        at org.gradle.api.internal.tasks.compile.IncrementalJavaCompilerSupport.execute(IncrementalJavaCompilerSupport.java:33)
        at org.gradle.api.internal.tasks.compile.IncrementalJavaCompilerSupport.execute(IncrementalJavaCompilerSupport.java:23)
        at org.gradle.api.tasks.compile.Compile.compile(Compile.java:60)
        at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:196)
        at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:102)
        at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:99)
        at org.gradle.api.tasks.compile.Compile_Decorated.invokeMethod(Unknown Source)
        at org.gradle.util.ReflectionUtil.invoke(ReflectionUtil.groovy:23)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$4.execute(AnnotationProcessingTaskFactory.java:150)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$4.execute(AnnotationProcessingTaskFactory.java:145)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:477)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:466)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:60)
        ... 78 more
Caused by: java.util.MissingResourceException: Can't find bundle for base name com.sun.tools.javac.resources.javac, locale en_US
        at com.sun.tools.javac.util.Messages.add(Messages.java:66)
        at com.sun.tools.javac.util.Messages.<init>(Messages.java:52)
        at com.sun.tools.javac.main.Main.getLocalizedString(Main.java:447)
        ... 101 more
    BUILD FAILED
  Total time: 3.97 secs

First of all, did you do a clean build? A clean build is required every time you switch between Gradle versions.

Are you saying that the error only occurs after ‘generateSrcFromXsd’ has run? Then maybe this task does something harmful (could be a JDK bug). As a workaround, you can switch back to the Ant Java compiler integration with ‘compileJava.useAnt = true’.

Can you post the output of ‘gradle -v’?

Thanks for the quick response.

Yes, this was a clean build.

That’s right - if ‘generateSrcFromXsd’ does not run (ie, it’s up to date) then the error does not occur.

I’ll try with another ant taskdef to confirm it’s an issue with XjcTask specifically.

Looks like using ‘compileJava.options.fork = true’ in all java projects avoids the issue (I had some issues with both ‘compileJava.useAnt’ and compileJava.options.useAnt).

Here’s output from ‘gradle -v’

------------------------------------------------------------
Gradle 1.0-rc-1
------------------------------------------------------------
  Gradle build time: Wednesday, April 11, 2012 11:13:24 AM UTC
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.8.2 compiled on December 20 2010
Ivy: 2.2.0
JVM: 1.6.0_30 (Sun Microsystems Inc. 20.5-b03)
OS: Windows 7 6.1 amd64

What issue did you have with ‘compileJava.options.useAnt = true’? Are you simply saying that it didn’t solve the problem? Anyway, the original problem is likely out of our control, so ‘compileJava.options.fork = true’ is a good solution.

Correct, ‘compileJava.options.useAnt = true’ did not solve the problem. I still saw the error with that enabled.

Like you said, it looks like the XJCTask “does something harmful”. I tried with a few other ant taskdefs and had no issues.

For reference, here’s the workaround we ended up with in the top-level build.gradle:

configure( allprojects.findAll {it.plugins.hasPlugin('java')} ) {
 compileJava.options.fork = true
}

Thank you kindly for all the help. Gradle rocks.

Actually, ‘fork = true’ will probably become the default at some point. It is smart enough not to fork a new process for every compile task, so the performance overhead should be negligible.

Here is how I would configure forking:

allprojects {
  tasks.withType(Compile) {
    options.fork = true
  }
}