reqorked Gradle 8 compatibility adding a task to extract envelope launcher
This commit is contained in:
@@ -10,6 +10,7 @@ import net.woggioni.envelope.Common;
|
||||
import net.woggioni.envelope.Constants;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.internal.file.CopyActionProcessingStreamAction;
|
||||
import org.gradle.api.internal.file.FileResolver;
|
||||
import org.gradle.api.internal.file.copy.CopyAction;
|
||||
@@ -23,6 +24,7 @@ import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.TaskContainer;
|
||||
import org.gradle.api.tasks.WorkResult;
|
||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
|
||||
import org.gradle.internal.Cast;
|
||||
@@ -31,16 +33,12 @@ import org.gradle.util.GradleVersion;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@@ -66,6 +64,7 @@ import static java.util.zip.Deflater.NO_COMPRESSION;
|
||||
public class EnvelopeJarTask extends AbstractArchiveTask {
|
||||
|
||||
private static final String MINIMUM_GRADLE_VERSION = "6.0";
|
||||
private static final String EXTRACT_LAUNCHER_TASK_NAME = "extractEnvelopeLauncher";
|
||||
|
||||
static {
|
||||
if (GradleVersion.current().compareTo(GradleVersion.version(MINIMUM_GRADLE_VERSION)) < 0) {
|
||||
@@ -74,6 +73,8 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
||||
}
|
||||
}
|
||||
|
||||
private final Provider<ExtractLauncherTask> extractLauncherTaskProvider;
|
||||
|
||||
@Getter(onMethod_ = {@Input, @Optional})
|
||||
private final Property<String> mainClass;
|
||||
|
||||
@@ -134,6 +135,15 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
||||
|
||||
@Inject
|
||||
public EnvelopeJarTask(ObjectFactory objects, FileResolver fileResolver) {
|
||||
Project rootProject = getProject().getRootProject();
|
||||
TaskContainer rootProjectTasks = rootProject.getTasks();
|
||||
if(rootProjectTasks.getNames().contains(EXTRACT_LAUNCHER_TASK_NAME)) {
|
||||
extractLauncherTaskProvider = rootProjectTasks.named(EXTRACT_LAUNCHER_TASK_NAME, ExtractLauncherTask.class);
|
||||
} else {
|
||||
extractLauncherTaskProvider = rootProject.getTasks().register(EXTRACT_LAUNCHER_TASK_NAME, ExtractLauncherTask.class);
|
||||
}
|
||||
getInputs().files(extractLauncherTaskProvider);
|
||||
|
||||
setGroup("build");
|
||||
setDescription("Creates an executable jar file, embedding all of its runtime dependencies");
|
||||
BasePluginExtension basePluginExtension = getProject().getExtensions().getByType(BasePluginExtension.class);
|
||||
@@ -151,42 +161,7 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
||||
mainClass.convention(javaApplication.getMainClass());
|
||||
mainModule.convention(javaApplication.getMainModule());
|
||||
}
|
||||
File launcherFile = new File(getTemporaryDir(), "launcher.jar");
|
||||
updateLauncherFile(launcherFile);
|
||||
from(getProject().tarTree(launcherFile), copySpec -> exclude(JarFile.MANIFEST_NAME));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void updateLauncherFile(File launcherFile) {
|
||||
byte[] buffer = new byte[0x10000];
|
||||
boolean launcherFileToBeWritten;
|
||||
if(launcherFile.exists()) {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
try (InputStream inputStream = new DigestInputStream(LauncherResource.instance.read(), md)) {
|
||||
Common.write2Stream(inputStream, new NullOutputStream(), buffer);
|
||||
}
|
||||
byte[] sourceDigest = md.digest();
|
||||
md.reset();
|
||||
try (InputStream inputStream = new DigestInputStream(new FileInputStream(launcherFile), md)) {
|
||||
Common.write2Stream(inputStream, new NullOutputStream(), buffer);
|
||||
}
|
||||
byte[] destinationDigest = md.digest();
|
||||
launcherFileToBeWritten = !Arrays.equals(sourceDigest, destinationDigest);
|
||||
} else {
|
||||
launcherFileToBeWritten = true;
|
||||
}
|
||||
if(launcherFileToBeWritten) {
|
||||
try (InputStream inputStream = LauncherResource.instance.read()) {
|
||||
try (OutputStream outputStream = new FileOutputStream(launcherFile)) {
|
||||
Common.write2Stream(inputStream, outputStream, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Input
|
||||
public String getLauncherArchiveHash() {
|
||||
return Common.bytesToHex(Common.computeSHA256Digest(LauncherResource.instance::read));
|
||||
from(getProject().tarTree(extractLauncherTaskProvider.map(ExtractLauncherTask::getLauncherTar)), copySpec -> exclude(JarFile.MANIFEST_NAME));
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
|
@@ -4,7 +4,6 @@ import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.BasePluginExtension;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.JavaExec;
|
||||
@@ -13,7 +12,6 @@ import org.gradle.api.tasks.bundling.Jar;
|
||||
public class EnvelopePlugin implements Plugin<Project> {
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
BasePluginExtension basePluginExtension = project.getExtensions().getByType(BasePluginExtension.class);
|
||||
Provider<EnvelopeJarTask> envelopeJarTaskProvider = project.getTasks().register("envelopeJar", EnvelopeJarTask.class, t -> {
|
||||
t.setGroup(BasePlugin.BUILD_GROUP);
|
||||
t.setDescription("Package the application in a single executable jar file");
|
||||
|
@@ -0,0 +1,38 @@
|
||||
package net.woggioni.gradle.envelope;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.envelope.Common;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ExtractLauncherTask extends DefaultTask {
|
||||
|
||||
@Getter(onMethod_ = @OutputFile)
|
||||
private final Path launcherTar;
|
||||
|
||||
@Input
|
||||
public byte[] getInputHash() {
|
||||
return LauncherResource.instance.getHash();
|
||||
}
|
||||
public ExtractLauncherTask() {
|
||||
Path tmpDir = getTemporaryDir().toPath();
|
||||
launcherTar = tmpDir.resolve("launcher.tar");
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
@SneakyThrows
|
||||
public void run() {
|
||||
try(InputStream inputStream = LauncherResource.instance.read();
|
||||
OutputStream outputStream = Files.newOutputStream(launcherTar)) {
|
||||
Common.write2Stream(inputStream, outputStream);
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,18 +3,25 @@ package net.woggioni.gradle.envelope;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.gradle.api.resources.ReadableResource;
|
||||
import org.gradle.api.resources.ResourceException;
|
||||
|
||||
final class LauncherResource implements ReadableResource {
|
||||
static final ReadableResource instance = new LauncherResource();
|
||||
static final LauncherResource instance = new LauncherResource();
|
||||
|
||||
private final URL url;
|
||||
@Getter
|
||||
private final byte[] hash;
|
||||
|
||||
private LauncherResource() {
|
||||
url = getClass().getResource(String.format("/LIB-INF/%s", getDisplayName()));
|
||||
hash = computeHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,4 +46,17 @@ final class LauncherResource implements ReadableResource {
|
||||
public String getBaseName() {
|
||||
return "launcher";
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private byte[] computeHash() {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
try(InputStream inputStream = new DigestInputStream(read(), md)) {
|
||||
byte[] buffer = new byte[0x10000];
|
||||
while(true) {
|
||||
int read = inputStream.read(buffer);
|
||||
if(read < 0) break;
|
||||
}
|
||||
}
|
||||
return md.digest();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user