I've been trying to move to Gradle for some time now. One of the things I have to do is automatically create additional entries in the WAR file based on those that would normally be added. For performance and other reasons I attempted to do this the same way it was done before by automating this inside a custom subclass of the War task. As I have to work around private visibility and final fields this is not as nice as I wanted, but it fails before it starts. The moment I added references to classes from the org.apache.tools.zip package, the build fails at runtime with the following stack trace:
17:44:32.888 [ERROR] [org.gradle.BuildExceptionReporter] FAILURE: Build failed with an exception.
17:44:32.900 [ERROR] [org.gradle.BuildExceptionReporter]
17:44:32.907 [ERROR] [org.gradle.BuildExceptionReporter] * Where:
17:44:32.914 [ERROR] [org.gradle.BuildExceptionReporter] Build file '...\build.gradle' line: 92
17:44:32.921 [ERROR] [org.gradle.BuildExceptionReporter]
17:44:32.928 [ERROR] [org.gradle.BuildExceptionReporter] * What went wrong:
17:44:32.935 [ERROR] [org.gradle.BuildExceptionReporter] A problem occurred evaluating root project '...'.
17:44:32.942 [ERROR] [org.gradle.BuildExceptionReporter] > Could not generate a proxy class for class ....ProblemWarTask.
17:44:32.953 [ERROR] [org.gradle.BuildExceptionReporter]
17:44:32.960 [ERROR] [org.gradle.BuildExceptionReporter] * Exception is:
17:44:32.969 [ERROR] [org.gradle.BuildExceptionReporter] org.gradle.api.GradleScriptException: A problem occurred evaluating root project '...'.
17:44:32.976 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:54)
17:44:32.983 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:127)
17:44:32.991 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.configuration.BuildScriptProcessor.evaluate(BuildScriptProcessor.java:38)
17:44:32.998 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.configuration.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:44)
17:44:33.005 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:464)
17:44:33.013 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:77)
17:44:33.020 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.configuration.DefaultBuildConfigurer$ConfigureProject.execute(DefaultBuildConfigurer.java:38)
17:44:33.027 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.configuration.DefaultBuildConfigurer$ConfigureProject.execute(DefaultBuildConfigurer.java:36)
17:44:33.034 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.AbstractProject.configure(AbstractProject.java:440)
17:44:33.041 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.AbstractProject.allprojects(AbstractProject.java:435)
17:44:33.048 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:32)
17:44:33.055 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:142)
17:44:33.062 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113)
17:44:33.069 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81)
17:44:33.077 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:38)
17:44:33.086 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:39)
17:44:33.095 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:25)
17:44:33.103 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50)
17:44:33.112 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
17:44:33.121 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:201)
17:44:33.130 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:174)
17:44:33.139 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:170)
17:44:33.148 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:139)
17:44:33.157 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
17:44:33.166 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
17:44:33.175 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.Main.doAction(Main.java:48)
17:44:33.182 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
17:44:33.190 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.Main.main(Main.java:39)
17:44:33.197 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:50)
17:44:33.206 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:32)
17:44:33.216 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.GradleMain.main(GradleMain.java:26)
17:44:33.227 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: org.gradle.api.GradleException: Could not generate a proxy class for class ....ProblemWarTask.
17:44:33.238 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.AbstractClassGenerator.generate(AbstractClassGenerator.java:201)
17:44:33.249 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.TaskFactory.createTaskObject(TaskFactory.java:105)
17:44:33.258 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.TaskFactory.createTask(TaskFactory.java:70)
17:44:33.266 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory.createTask(AnnotationProcessingTaskFactory.java:93)
17:44:33.276 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DependencyAutoWireTaskFactory.createTask(DependencyAutoWireTaskFactory.java:39)
17:44:33.285 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.DefaultTaskContainer.add(DefaultTaskContainer.java:56)
17:44:33.294 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.AbstractProject.task(AbstractProject.java:921)
17:44:33.301 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:216)
17:44:33.311 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:122)
17:44:33.319 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:147)
17:44:33.328 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.groovy.scripts.BasicScript.methodMissing(BasicScript.java:83)
17:44:33.335 [ERROR] [org.gradle.BuildExceptionReporter] at build_77lv568h8hqtuhsa63froq7bcr.run(...\build.gradle:92)
17:44:33.343 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:52)
17:44:33.352 [ERROR] [org.gradle.BuildExceptionReporter] ... 30 more
17:44:33.362 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: java.lang.NoClassDefFoundError: Lorg/apache/tools/zip/ZipOutputStream;
17:44:33.370 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.AbstractClassGenerator.generate(AbstractClassGenerator.java:100)
17:44:33.379 [ERROR] [org.gradle.BuildExceptionReporter] ... 42 more
17:44:33.387 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: java.lang.ClassNotFoundException: org.apache.tools.zip.ZipOutputStream
17:44:33.395 [ERROR] [org.gradle.BuildExceptionReporter] ... 43 more
17:44:33.403 [ERROR] [org.gradle.BuildExceptionReporter]
17:44:33.411 [LIFECYCLE] [org.gradle.BuildResultLogger]
17:44:33.419 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD FAILED
This is still mostly learning about Gradle. My biggest issue right now is actually not understanding why this happens and what am I missing in general (i.e. if/when I write other tasks). How come this passes the compilation stage just fine (buildSrc.jar is created just fine) but fails at runtime?
Here's the slightly obfuscated source code of this (you'll see that it is mostly a copy of Gradle's own code - namely the Zip task):
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import org.apache.tools.zip.UnixStat;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.gradle.api.file.FileVisitDetails;
import org.gradle.api.GradleException;
import org.gradle.api.internal.file.archive.ZipCopyAction;
import org.gradle.api.internal.file.archive.ZipCopySpecVisitor;
import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.internal.file.copy.CopyActionImpl;
import org.gradle.api.internal.file.copy.CopySpecImpl;
import org.gradle.api.internal.file.copy.CopySpecVisitor;
import org.gradle.api.internal.file.copy.MappingCopySpecVisitor;
import org.gradle.api.internal.file.copy.NormalizingCopySpecVisitor;
import org.gradle.api.internal.file.copy.ReadableCopySpec;
import org.gradle.api.internal.file.copy.ZipCompressor;
import org.gradle.api.internal.file.copy.ZipDeflatedCompressor;
import org.gradle.api.internal.file.FileResolver;
import org.gradle.api.tasks.bundling.War;
import org.gradle.api.tasks.bundling.Zip;
import org.gradle.api.UncheckedIOException;
import org.gradle.internal.nativeplatform.filesystem.FileSystems;
class ProblemWarTask extends War {
private ZipCopyActionImpl copyAction = null;
public ProblemWarTask() {}
protected synchronized Zip.ZipCopyActionImpl getCopyAction() {
if (copyAction == null) {
copyAction = new ProblemWarCopyActionImpl(getServices().get(FileResolver.class));
}
return copyAction;
}
protected class ProblemWarCopyActionImpl extends Zip.ZipCopyActionImpl {
private final CopySpecVisitor visitor;
public ProblemWarCopyActionImpl(FileResolver fileResolver) {
super((FileResolver) fileResolver);
visitor = new MappingCopySpecVisitor(new NormalizingCopySpecVisitor(new ProblemWarCopySpecVisitor()), FileSystems.getDefault());
}
public void execute() {
visitor.startVisit(this);
for (ReadableCopySpec spec : getRootSpec().getAllSpecs()) {
visitor.visitSpec(spec);
spec.getSource().visit(visitor);
}
visitor.endVisit();
}
public boolean getDidWork() {
return visitor.getDidWork();
}
}
protected class ProblemWarCopySpecVisitor extends ZipCopySpecVisitor {
private ZipOutputStream zipOutStr;
private File zipFile;
public void startVisit(CopyAction action) {
ZipCopyAction archiveAction = (ZipCopyAction) action;
zipFile = archiveAction.getArchivePath();
try {
zipOutStr = archiveAction.getCompressor().createArchiveOutputStream(zipFile);
} catch (Exception e) {
throw new GradleException(String.format("Could not create ZIP '%s'.", zipFile), e);
}
}
public void endVisit() {
try {
zipOutStr.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
} finally {
zipOutStr = null;
}
}
public void visitFile(FileVisitDetails fileDetails) {
try {
ZipEntry archiveEntry = new ZipEntry(fileDetails.getRelativePath().getPathString());
archiveEntry.setTime(fileDetails.getLastModified());
archiveEntry.setUnixMode(UnixStat.FILE_FLAG | fileDetails.getMode());
zipOutStr.putNextEntry(archiveEntry);
fileDetails.copyTo(zipOutStr);
zipOutStr.closeEntry();
} catch (Exception e) {
throw new GradleException(String.format("Could not add %s to ZIP '%s'.", fileDetails, zipFile), e);
}
// Now do a little more - add stuff
try {
if (...) {
byte[] buffer;
...
ZipEntry archiveEntry = new ZipEntry(secondPath);
archiveEntry.setTime(fileDetails.getLastModified());
archiveEntry.setUnixMode(UnixStat.FILE_FLAG | fileDetails.getMode());
zipOutStr.putNextEntry(archiveEntry);
zipOutStr.write(buffer, 0, buffer.length);
zipOutStr.closeEntry();
}
} catch (Exception e) {
throw new GradleException(String.format("Could not add secondary form of %s to ZIP '%s'.", fileDetails, zipFile), e);
}
}
public void visitDir(FileVisitDetails dirDetails) {
try {
// Trailing slash in name indicates that entry is a directory
ZipEntry archiveEntry = new ZipEntry(dirDetails.getRelativePath().getPathString() + '/');
archiveEntry.setTime(dirDetails.getLastModified());
archiveEntry.setUnixMode(UnixStat.DIR_FLAG | dirDetails.getMode());
zipOutStr.putNextEntry(archiveEntry);
zipOutStr.closeEntry();
} catch (Exception e) {
throw new GradleException(String.format("Could not add %s to ZIP '%s'.", dirDetails, zipFile), e);
}
}
}
}
Presently the build script itself is not doing anything special with it:
task war(type: ....ProblemWarTask) {
...
}
The body is is the same as I used for the 'War' task and even for initial experimenting with this one (ProblemWarTask). Exception started happening when I added references to the package noted. What bothers me is how can a 'War' task run just fine when it has the same set of runtime dependencies as this one in the end.
This is with Gradle 1.5. I also tried adding the following to build.gradle but did not help (same error):
buildscript {
dependencies {
classpath files(".../gradle/lib/ant-1.8.4.jar")
}
}
Edit - tried with Gradle 1.6, no change. Posted in Gradle forums too:
Edit 2 - isolated sample files can be found at: