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 net.woggioni.envelope.Constants;
|
||||||
import org.gradle.api.Action;
|
import org.gradle.api.Action;
|
||||||
import org.gradle.api.GradleException;
|
import org.gradle.api.GradleException;
|
||||||
|
import org.gradle.api.Project;
|
||||||
import org.gradle.api.internal.file.CopyActionProcessingStreamAction;
|
import org.gradle.api.internal.file.CopyActionProcessingStreamAction;
|
||||||
import org.gradle.api.internal.file.FileResolver;
|
import org.gradle.api.internal.file.FileResolver;
|
||||||
import org.gradle.api.internal.file.copy.CopyAction;
|
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.provider.Provider;
|
||||||
import org.gradle.api.tasks.Input;
|
import org.gradle.api.tasks.Input;
|
||||||
import org.gradle.api.tasks.Optional;
|
import org.gradle.api.tasks.Optional;
|
||||||
|
import org.gradle.api.tasks.TaskContainer;
|
||||||
import org.gradle.api.tasks.WorkResult;
|
import org.gradle.api.tasks.WorkResult;
|
||||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
|
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
|
||||||
import org.gradle.internal.Cast;
|
import org.gradle.internal.Cast;
|
||||||
@@ -31,16 +33,12 @@ import org.gradle.util.GradleVersion;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.DigestInputStream;
|
|
||||||
import java.security.DigestOutputStream;
|
import java.security.DigestOutputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -66,6 +64,7 @@ import static java.util.zip.Deflater.NO_COMPRESSION;
|
|||||||
public class EnvelopeJarTask extends AbstractArchiveTask {
|
public class EnvelopeJarTask extends AbstractArchiveTask {
|
||||||
|
|
||||||
private static final String MINIMUM_GRADLE_VERSION = "6.0";
|
private static final String MINIMUM_GRADLE_VERSION = "6.0";
|
||||||
|
private static final String EXTRACT_LAUNCHER_TASK_NAME = "extractEnvelopeLauncher";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (GradleVersion.current().compareTo(GradleVersion.version(MINIMUM_GRADLE_VERSION)) < 0) {
|
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})
|
@Getter(onMethod_ = {@Input, @Optional})
|
||||||
private final Property<String> mainClass;
|
private final Property<String> mainClass;
|
||||||
|
|
||||||
@@ -134,6 +135,15 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public EnvelopeJarTask(ObjectFactory objects, FileResolver fileResolver) {
|
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");
|
setGroup("build");
|
||||||
setDescription("Creates an executable jar file, embedding all of its runtime dependencies");
|
setDescription("Creates an executable jar file, embedding all of its runtime dependencies");
|
||||||
BasePluginExtension basePluginExtension = getProject().getExtensions().getByType(BasePluginExtension.class);
|
BasePluginExtension basePluginExtension = getProject().getExtensions().getByType(BasePluginExtension.class);
|
||||||
@@ -151,42 +161,7 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
mainClass.convention(javaApplication.getMainClass());
|
mainClass.convention(javaApplication.getMainClass());
|
||||||
mainModule.convention(javaApplication.getMainModule());
|
mainModule.convention(javaApplication.getMainModule());
|
||||||
}
|
}
|
||||||
File launcherFile = new File(getTemporaryDir(), "launcher.jar");
|
from(getProject().tarTree(extractLauncherTaskProvider.map(ExtractLauncherTask::getLauncherTar)), copySpec -> exclude(JarFile.MANIFEST_NAME));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@@ -4,7 +4,6 @@ import org.gradle.api.DefaultTask;
|
|||||||
import org.gradle.api.Plugin;
|
import org.gradle.api.Plugin;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
import org.gradle.api.plugins.BasePlugin;
|
import org.gradle.api.plugins.BasePlugin;
|
||||||
import org.gradle.api.plugins.BasePluginExtension;
|
|
||||||
import org.gradle.api.plugins.JavaPlugin;
|
import org.gradle.api.plugins.JavaPlugin;
|
||||||
import org.gradle.api.provider.Provider;
|
import org.gradle.api.provider.Provider;
|
||||||
import org.gradle.api.tasks.JavaExec;
|
import org.gradle.api.tasks.JavaExec;
|
||||||
@@ -13,7 +12,6 @@ import org.gradle.api.tasks.bundling.Jar;
|
|||||||
public class EnvelopePlugin implements Plugin<Project> {
|
public class EnvelopePlugin implements Plugin<Project> {
|
||||||
@Override
|
@Override
|
||||||
public void apply(Project project) {
|
public void apply(Project project) {
|
||||||
BasePluginExtension basePluginExtension = project.getExtensions().getByType(BasePluginExtension.class);
|
|
||||||
Provider<EnvelopeJarTask> envelopeJarTaskProvider = project.getTasks().register("envelopeJar", EnvelopeJarTask.class, t -> {
|
Provider<EnvelopeJarTask> envelopeJarTaskProvider = project.getTasks().register("envelopeJar", EnvelopeJarTask.class, t -> {
|
||||||
t.setGroup(BasePlugin.BUILD_GROUP);
|
t.setGroup(BasePlugin.BUILD_GROUP);
|
||||||
t.setDescription("Package the application in a single executable jar file");
|
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.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.security.DigestInputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.gradle.api.resources.ReadableResource;
|
import org.gradle.api.resources.ReadableResource;
|
||||||
import org.gradle.api.resources.ResourceException;
|
import org.gradle.api.resources.ResourceException;
|
||||||
|
|
||||||
final class LauncherResource implements ReadableResource {
|
final class LauncherResource implements ReadableResource {
|
||||||
static final ReadableResource instance = new LauncherResource();
|
static final LauncherResource instance = new LauncherResource();
|
||||||
|
|
||||||
private final URL url;
|
private final URL url;
|
||||||
|
@Getter
|
||||||
|
private final byte[] hash;
|
||||||
|
|
||||||
private LauncherResource() {
|
private LauncherResource() {
|
||||||
url = getClass().getResource(String.format("/LIB-INF/%s", getDisplayName()));
|
url = getClass().getResource(String.format("/LIB-INF/%s", getDisplayName()));
|
||||||
|
hash = computeHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,4 +46,17 @@ final class LauncherResource implements ReadableResource {
|
|||||||
public String getBaseName() {
|
public String getBaseName() {
|
||||||
return "launcher";
|
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