私はしばらくGradleに移行しようとしています。私がしなければならないことの 1 つは、通常追加されるエントリに基づいて、WAR ファイルに追加のエントリを自動的に作成することです。パフォーマンスやその他の理由から、戦争タスクのカスタム サブクラス内でこれを自動化することにより、以前と同じ方法でこれを実行しようとしました。プライベートな可視性と最終フィールドに対処する必要があるため、これは私が望んでいたほど良くはありませんが、開始する前に失敗します。org.apache.tools.zip パッケージからクラスへの参照を追加した瞬間、ビルドは実行時に次のスタック トレースで失敗します。
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
これはまだGradleについてほとんど学んでいます。現在の私の最大の問題は、なぜこれが起こるのか、一般的に何が欠けているのか (つまり、他のタスクを書く場合) を理解していないことです。これはコンパイル段階を問題なく通過しますが (buildSrc.jar は問題なく作成されます)、実行時に失敗するのはなぜですか?
これを少し難読化したソース コードを次に示します (ほとんどが Gradle 独自のコード、つまり Zip タスクのコピーであることがわかります)。
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);
}
}
}
}
現在、ビルド スクリプト自体は特別なことを行っていません。
task war(type: ....ProblemWarTask) {
...
}
本体は、「戦争」タスクで使用したものと同じであり、このタスク (ProblemWarTask) の最初の実験でも同じです。注意したパッケージへの参照を追加すると、例外が発生し始めました。私を悩ませているのは、最終的にこれと同じランタイム依存関係のセットがある場合、「戦争」タスクがどのようにうまく実行できるかということです。
これはGradle 1.5です。また、build.gradle に以下を追加しようとしましたが、役に立ちませんでした (同じエラー):
buildscript {
dependencies {
classpath files(".../gradle/lib/ant-1.8.4.jar")
}
}
編集- Gradle 1.6 で試しましたが、変更はありません。Gradle フォーラムにも投稿:
編集 2 - 分離されたサンプル ファイルは次の場所にあります。