added Manifest to EnvelopeJarTask
This commit is contained in:
@@ -3,5 +3,5 @@ publishMavenRepositoryUrl=https://mvn.woggioni.net/
|
|||||||
|
|
||||||
lys.version = 0.1-SNAPSHOT
|
lys.version = 0.1-SNAPSHOT
|
||||||
|
|
||||||
version.envelope=2022.08
|
version.envelope=2022.09
|
||||||
version.gradle=7.5.1
|
version.gradle=7.5.1
|
||||||
|
@@ -1,34 +1,45 @@
|
|||||||
package net.woggioni.gradle.envelope;
|
package net.woggioni.gradle.envelope;
|
||||||
|
|
||||||
|
import groovy.lang.Closure;
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.woggioni.envelope.Common;
|
import net.woggioni.envelope.Common;
|
||||||
import net.woggioni.envelope.Constants;
|
import net.woggioni.envelope.Constants;
|
||||||
|
import org.gradle.api.Action;
|
||||||
import org.gradle.api.GradleException;
|
import org.gradle.api.GradleException;
|
||||||
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.copy.CopyAction;
|
import org.gradle.api.internal.file.copy.CopyAction;
|
||||||
import org.gradle.api.internal.file.copy.CopyActionProcessingStream;
|
import org.gradle.api.internal.file.copy.CopyActionProcessingStream;
|
||||||
import org.gradle.api.internal.file.copy.FileCopyDetailsInternal;
|
import org.gradle.api.internal.file.copy.FileCopyDetailsInternal;
|
||||||
|
import org.gradle.api.java.archives.internal.DefaultManifest;
|
||||||
import org.gradle.api.model.ObjectFactory;
|
import org.gradle.api.model.ObjectFactory;
|
||||||
import org.gradle.api.plugins.BasePluginExtension;
|
import org.gradle.api.plugins.BasePluginExtension;
|
||||||
import org.gradle.api.plugins.JavaApplication;
|
import org.gradle.api.plugins.JavaApplication;
|
||||||
import org.gradle.api.provider.Property;
|
import org.gradle.api.provider.Property;
|
||||||
|
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.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.util.GradleVersion;
|
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.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.DigestOutputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -39,6 +50,7 @@ import java.util.function.Supplier;
|
|||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
@@ -69,9 +81,38 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
@Getter(onMethod_ = {@Input})
|
@Getter(onMethod_ = {@Input})
|
||||||
private final Map<String, String> systemProperties = new TreeMap<>();
|
private final Map<String, String> systemProperties = new TreeMap<>();
|
||||||
|
|
||||||
|
private final org.gradle.api.java.archives.Manifest manifest;
|
||||||
|
|
||||||
|
public org.gradle.api.java.archives.Manifest manifest() {
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
public Set<Map.Entry<Object, Object>> getJavaAgents() {
|
@SneakyThrows
|
||||||
return Collections.unmodifiableSet(javaAgents.entrySet());
|
public byte[] getManifestHash() {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("md5");
|
||||||
|
try(OutputStream outputStream = new DigestOutputStream(NullOutputStream.getInstance(), md)) {
|
||||||
|
ManifestUtils.generateJavaManifest(manifest).write(outputStream);
|
||||||
|
}
|
||||||
|
return md.digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.gradle.api.java.archives.Manifest manifest(Closure<org.gradle.api.java.archives.Manifest> closure) {
|
||||||
|
closure.setDelegate(manifest);
|
||||||
|
closure.call();
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.gradle.api.java.archives.Manifest manifest(Action<? super org.gradle.api.java.archives.Manifest> action) {
|
||||||
|
action.execute(manifest);
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input
|
||||||
|
public Set<String> getJavaAgents() {
|
||||||
|
return Collections.unmodifiableSet(javaAgents.entrySet().stream()
|
||||||
|
.map(entry -> entry.getKey().toString() + ':' + entry.getValue().toString())
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void javaAgent(String className, String args) {
|
public void javaAgent(String className, String args) {
|
||||||
@@ -88,7 +129,7 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public EnvelopeJarTask(ObjectFactory objects) {
|
public EnvelopeJarTask(ObjectFactory objects, FileResolver fileResolver) {
|
||||||
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);
|
||||||
@@ -98,6 +139,7 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
getArchiveVersion().convention(getProject().getVersion().toString());
|
getArchiveVersion().convention(getProject().getVersion().toString());
|
||||||
getArchiveAppendix().convention("envelope");
|
getArchiveAppendix().convention("envelope");
|
||||||
|
|
||||||
|
manifest = new DefaultManifest(fileResolver);
|
||||||
mainClass = objects.property(String.class);
|
mainClass = objects.property(String.class);
|
||||||
mainModule = objects.property(String.class);
|
mainModule = objects.property(String.class);
|
||||||
JavaApplication javaApplication = getProject().getExtensions().findByType(JavaApplication.class);
|
JavaApplication javaApplication = getProject().getExtensions().findByType(JavaApplication.class);
|
||||||
@@ -227,7 +269,7 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public WorkResult execute(@Nonnull CopyActionProcessingStream copyActionProcessingStream) {
|
public WorkResult execute(@Nonnull CopyActionProcessingStream copyActionProcessingStream) {
|
||||||
Manifest manifest = new Manifest();
|
Manifest manifest = ManifestUtils.generateJavaManifest(EnvelopeJarTask.this.manifest);
|
||||||
Attributes mainAttributes = manifest.getMainAttributes();
|
Attributes mainAttributes = manifest.getMainAttributes();
|
||||||
mainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
mainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||||
mainAttributes.put(Attributes.Name.MAIN_CLASS, Constants.DEFAULT_LAUNCHER);
|
mainAttributes.put(Attributes.Name.MAIN_CLASS, Constants.DEFAULT_LAUNCHER);
|
||||||
@@ -310,4 +352,72 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
class ManifestUtils {
|
||||||
|
static Manifest generateJavaManifest(org.gradle.api.java.archives.Manifest gradleManifest) {
|
||||||
|
Manifest javaManifest = new Manifest();
|
||||||
|
addMainAttributesToJavaManifest(gradleManifest, javaManifest);
|
||||||
|
addSectionAttributesToJavaManifest(gradleManifest, javaManifest);
|
||||||
|
return javaManifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addMainAttributesToJavaManifest(org.gradle.api.java.archives.Manifest gradleManifest, Manifest javaManifest) {
|
||||||
|
fillAttributes(gradleManifest.getAttributes(), javaManifest.getMainAttributes());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addSectionAttributesToJavaManifest(org.gradle.api.java.archives.Manifest gradleManifest, Manifest javaManifest) {
|
||||||
|
Iterator<Map.Entry<String, org.gradle.api.java.archives.Attributes>> it = gradleManifest.getSections().entrySet().iterator();
|
||||||
|
|
||||||
|
while(it.hasNext()) {
|
||||||
|
Map.Entry<String, org.gradle.api.java.archives.Attributes> entry = it.next();
|
||||||
|
String sectionName = entry.getKey();
|
||||||
|
java.util.jar.Attributes targetAttributes = new java.util.jar.Attributes();
|
||||||
|
fillAttributes(entry.getValue(), targetAttributes);
|
||||||
|
javaManifest.getEntries().put(sectionName, targetAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillAttributes(org.gradle.api.java.archives.Attributes attributes, java.util.jar.Attributes targetAttributes) {
|
||||||
|
Iterator<Map.Entry<String, Object>> it = attributes.entrySet().iterator();
|
||||||
|
|
||||||
|
while(it.hasNext()) {
|
||||||
|
Map.Entry<String, Object> entry = it.next();
|
||||||
|
String mainAttributeName = entry.getKey();
|
||||||
|
String mainAttributeValue = resolveValueToString(entry.getValue());
|
||||||
|
if (mainAttributeValue != null) {
|
||||||
|
targetAttributes.putValue(mainAttributeName, mainAttributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String resolveValueToString(Object value) {
|
||||||
|
Object underlyingValue = value;
|
||||||
|
if (value instanceof Provider) {
|
||||||
|
Provider<?> provider = Cast.uncheckedCast(value);
|
||||||
|
if (!provider.isPresent()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
underlyingValue = provider.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return underlyingValue.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
class NullOutputStream extends OutputStream {
|
||||||
|
@Getter
|
||||||
|
private static final OutputStream instance = new NullOutputStream();
|
||||||
|
public void write(byte[] b, int off, int len) {}
|
||||||
|
|
||||||
|
public void write(int b) {}
|
||||||
|
|
||||||
|
public void write(byte[] b) {}
|
||||||
}
|
}
|
Reference in New Issue
Block a user