added documentation
This commit is contained in:
113
README.md
Normal file
113
README.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
## Overview
|
||||||
|
Envelope is a simple Gradle plugin that allows you to create an executable jar file
|
||||||
|
that includes all runtime dependencies and can be executed with a simple
|
||||||
|
|
||||||
|
```bash
|
||||||
|
java -jar my-app.jar
|
||||||
|
```
|
||||||
|
It supports JPMS, embedded system properties, Java agents, extra folders to be added to classpath.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Declare the plugin in your build's `settings.gradle` like this
|
||||||
|
```groovy
|
||||||
|
|
||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = 'https://woggioni.net/mvn/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id "net.woggioni.gradle.envelope" version "2023.09.25"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then add it to a project's `build.gradle`
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
plugins {
|
||||||
|
id 'net.woggioni.gradle.envelope'
|
||||||
|
}
|
||||||
|
|
||||||
|
envelopeJar {
|
||||||
|
mainClass = 'your.main.Class'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The plugin adds 2 tasks to your project:
|
||||||
|
|
||||||
|
- `envelopeJar` of type `net.woggioni.gradle.envelope.EnvelopeJarTask` that creates the executable jar in the project's libraries folder
|
||||||
|
- `envelopeRun` of type `org.gradle.api.tasks.JavaExec` which launches the jar created by the `envelopeJar` task
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
`EnvelopeJarTask` has several properties useful for configuration purposes:
|
||||||
|
|
||||||
|
###### mainClass
|
||||||
|
|
||||||
|
This string property sets the class that will be searched for the `main` method to start the application
|
||||||
|
|
||||||
|
###### mainModule
|
||||||
|
|
||||||
|
When this string property is set, the jar file will be started in JPMS mode (if running on Java 9+) and
|
||||||
|
this module will be searched for the main class, if the `mainClass` is not set the main class specified
|
||||||
|
in the module descriptor will be loaded instead
|
||||||
|
|
||||||
|
###### systemProperties
|
||||||
|
|
||||||
|
This is a map that contains Java system properties that will be set before your application starts
|
||||||
|
|
||||||
|
###### extraClasspath
|
||||||
|
|
||||||
|
This is a list of strings representing filesystem paths that will be added to the classpath (if running in classpath mode)
|
||||||
|
or to the module path (if running in JPMS mode) when the application starts.
|
||||||
|
|
||||||
|
Relative paths and interpolation with Java System properties and environmental variables are supported:
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
This looks for a `plugin` folder in the user's home directory
|
||||||
|
```
|
||||||
|
${env:HOME}/plugins
|
||||||
|
```
|
||||||
|
|
||||||
|
Same using Java system properties instead
|
||||||
|
```
|
||||||
|
${sys:user.home}/plugins
|
||||||
|
```
|
||||||
|
|
||||||
|
###### javaAgent
|
||||||
|
This is a method accepting 2 strings, the first is the Java agent classname and the second one is the java agent arguments.
|
||||||
|
It can be invoked multiple times to setup multiple java agents for the same JAR file.
|
||||||
|
All the java agents will be invoked before the application startup.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
plugins {
|
||||||
|
id 'net.woggioni.gradle.envelope'
|
||||||
|
}
|
||||||
|
|
||||||
|
envelopeJar {
|
||||||
|
mainClass = 'your.main.Class'
|
||||||
|
mainModule = 'your.main.module'
|
||||||
|
|
||||||
|
systemProperties = [
|
||||||
|
'some.property' : 'Some value'
|
||||||
|
]
|
||||||
|
|
||||||
|
extraClasspath = ["plugins"]
|
||||||
|
|
||||||
|
javaAgent('your.java.agent.Class', 'optional agent arguments')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Limitations
|
||||||
|
|
||||||
|
This plugin requires Gradle >= 6.0 and Java >=0 8 to build the executable jar file.
|
||||||
|
The assembled envelope jar requires and Java >= 8 to run, if only `mainClass` is specified,
|
||||||
|
if both `mainModule` and `mainClass` are specified the generated jar file will (try to) run in classpath mode on Java 8
|
||||||
|
and in JPMS mode on Java > 8.
|
@@ -256,4 +256,13 @@ public class Common {
|
|||||||
public static <T> Stream<T> opt2Stream(Optional<T> opt) {
|
public static <T> Stream<T> opt2Stream(Optional<T> opt) {
|
||||||
return opt.map(Stream::of).orElse(Stream.empty());
|
return opt.map(Stream::of).orElse(Stream.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> Optional<T> or(Supplier<T> ...suppliers) {
|
||||||
|
Optional<T> result = Optional.empty();
|
||||||
|
for(Supplier<T> supplier : suppliers) {
|
||||||
|
T value = supplier.get();
|
||||||
|
if(value != null) return Optional.of(value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,13 @@ public class Constants {
|
|||||||
public static final String ENTRY_HASH = "SHA-256-Digest";
|
public static final String ENTRY_HASH = "SHA-256-Digest";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class JvmProperties {
|
||||||
|
private static final String PREFIX = "envelope.";
|
||||||
|
public static final String MAIN_MODULE = PREFIX + "main.module";
|
||||||
|
public static final String MAIN_CLASS = PREFIX + "main.class";
|
||||||
|
public static final String EXTRA_CLASSPATH = PREFIX + "extra.classpath";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This value is used as a default file timestamp for all the zip entries when
|
* This value is used as a default file timestamp for all the zip entries when
|
||||||
* <a href="https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/bundling/AbstractArchiveTask.html#isPreserveFileTimestamps--">AbstractArchiveTask.isPreserveFileTimestamps</a>
|
* <a href="https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/bundling/AbstractArchiveTask.html#isPreserveFileTimestamps--">AbstractArchiveTask.isPreserveFileTimestamps</a>
|
||||||
|
@@ -3,5 +3,5 @@ publishMavenRepositoryUrl=https://mvn.woggioni.net/
|
|||||||
|
|
||||||
lys.version = 2023.08.28
|
lys.version = 2023.08.28
|
||||||
|
|
||||||
version.envelope=2023.08.28
|
version.envelope=2023.09.25
|
||||||
version.gradle=7.6
|
version.gradle=7.6
|
||||||
|
@@ -19,7 +19,6 @@ import java.util.Collections;
|
|||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -30,6 +29,7 @@ import java.util.jar.Manifest;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.woggioni.envelope.Common.or;
|
||||||
import static net.woggioni.envelope.Constants.EXTRA_CLASSPATH_ENTRY_SEPARATOR;
|
import static net.woggioni.envelope.Constants.EXTRA_CLASSPATH_ENTRY_SEPARATOR;
|
||||||
|
|
||||||
public class Launcher {
|
public class Launcher {
|
||||||
@@ -78,7 +78,10 @@ public class Launcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<JarFile> getExtraClasspath(Attributes mainAttributes) {
|
private static Stream<JarFile> getExtraClasspath(Attributes mainAttributes) {
|
||||||
return Common.opt2Stream(Optional.ofNullable(mainAttributes.getValue(Constants.ManifestAttributes.EXTRA_CLASSPATH))
|
return Common.opt2Stream(or(
|
||||||
|
() -> System.getProperty(Constants.JvmProperties.EXTRA_CLASSPATH),
|
||||||
|
() -> mainAttributes.getValue(Constants.ManifestAttributes.EXTRA_CLASSPATH)
|
||||||
|
)
|
||||||
.map(manifestAttribute -> {
|
.map(manifestAttribute -> {
|
||||||
Map<String, Map<String, Object>> dictMap = createContextMap();
|
Map<String, Map<String, Object>> dictMap = createContextMap();
|
||||||
return Common.renderTemplate(manifestAttribute, Collections.emptyMap(), dictMap);
|
return Common.renderTemplate(manifestAttribute, Collections.emptyMap(), dictMap);
|
||||||
@@ -93,8 +96,9 @@ public class Launcher {
|
|||||||
cursor,
|
cursor,
|
||||||
extraClasspathString.length()
|
extraClasspathString.length()
|
||||||
);
|
);
|
||||||
|
String classpathEntry = extraClasspathString.substring(cursor, sep < 0 ? extraClasspathString.length() : sep);
|
||||||
|
paths.add(classpathEntry);
|
||||||
if(sep < 0) break;
|
if(sep < 0) break;
|
||||||
paths.add(extraClasspathString.substring(cursor, sep));
|
|
||||||
cursor = sep + 1;
|
cursor = sep + 1;
|
||||||
}
|
}
|
||||||
return paths;
|
return paths;
|
||||||
@@ -143,8 +147,14 @@ public class Launcher {
|
|||||||
Manifest mf = currentJar.getManifest();
|
Manifest mf = currentJar.getManifest();
|
||||||
Attributes mainAttributes = mf.getMainAttributes();
|
Attributes mainAttributes = mf.getMainAttributes();
|
||||||
|
|
||||||
String mainClassName = mainAttributes.getValue(Constants.ManifestAttributes.MAIN_CLASS);
|
String mainClassName = or(
|
||||||
String mainModuleName = mainAttributes.getValue(Constants.ManifestAttributes.MAIN_MODULE);
|
() -> System.getProperty(Constants.JvmProperties.MAIN_CLASS),
|
||||||
|
() -> mainAttributes.getValue(Constants.ManifestAttributes.MAIN_CLASS)
|
||||||
|
).orElse(null);
|
||||||
|
String mainModuleName = or(
|
||||||
|
() -> System.getProperty(Constants.JvmProperties.MAIN_MODULE),
|
||||||
|
() -> mainAttributes.getValue(Constants.ManifestAttributes.MAIN_MODULE)
|
||||||
|
).orElse(null);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
List<JarFile> classpath = new ArrayList<>();
|
List<JarFile> classpath = new ArrayList<>();
|
||||||
URL libraryTocResource = Launcher.class.getClassLoader().getResource(Constants.LIBRARIES_TOC);
|
URL libraryTocResource = Launcher.class.getClassLoader().getResource(Constants.LIBRARIES_TOC);
|
||||||
|
@@ -85,6 +85,7 @@ class MainRunner {
|
|||||||
ModuleLayer layer = controller.layer();
|
ModuleLayer layer = controller.layer();
|
||||||
Module mainModule = layer.findModule(mainModuleName).orElseThrow(
|
Module mainModule = layer.findModule(mainModuleName).orElseThrow(
|
||||||
() -> new IllegalStateException(String.format("Main module '%s' not found", mainModuleName)));
|
() -> new IllegalStateException(String.format("Main module '%s' not found", mainModuleName)));
|
||||||
|
Thread.currentThread().setContextClassLoader(mainModule.getClassLoader());
|
||||||
Optional<String> mainClassOpt = Optional.ofNullable(mainClassName);
|
Optional<String> mainClassOpt = Optional.ofNullable(mainClassName);
|
||||||
runner.accept(Optional.ofNullable(mainClassName)
|
runner.accept(Optional.ofNullable(mainClassName)
|
||||||
.or(() -> mainModule.getDescriptor().mainClass())
|
.or(() -> mainModule.getDescriptor().mainClass())
|
||||||
|
@@ -18,9 +18,11 @@ 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.java.archives.internal.DefaultManifest;
|
||||||
import org.gradle.api.model.ObjectFactory;
|
import org.gradle.api.model.ObjectFactory;
|
||||||
|
import org.gradle.api.plugins.BasePlugin;
|
||||||
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.ListProperty;
|
import org.gradle.api.provider.ListProperty;
|
||||||
|
import org.gradle.api.provider.MapProperty;
|
||||||
import org.gradle.api.provider.Property;
|
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;
|
||||||
@@ -60,10 +62,12 @@ import java.util.zip.ZipOutputStream;
|
|||||||
|
|
||||||
import static java.util.zip.Deflater.BEST_COMPRESSION;
|
import static java.util.zip.Deflater.BEST_COMPRESSION;
|
||||||
import static java.util.zip.Deflater.NO_COMPRESSION;
|
import static java.util.zip.Deflater.NO_COMPRESSION;
|
||||||
|
import static net.woggioni.gradle.envelope.EnvelopePlugin.ENVELOPE_GROUP_NAME;
|
||||||
|
|
||||||
@SuppressWarnings({"unused" })
|
@SuppressWarnings({"unused" })
|
||||||
public class EnvelopeJarTask extends AbstractArchiveTask {
|
public abstract class EnvelopeJarTask extends AbstractArchiveTask {
|
||||||
|
|
||||||
|
private static final String DEFAULT_ARCHIVE_APPENDIX = ENVELOPE_GROUP_NAME;
|
||||||
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";
|
private static final String EXTRACT_LAUNCHER_TASK_NAME = "extractEnvelopeLauncher";
|
||||||
|
|
||||||
@@ -76,19 +80,21 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
|
|
||||||
private final Provider<ExtractLauncherTask> extractLauncherTaskProvider;
|
private final Provider<ExtractLauncherTask> extractLauncherTaskProvider;
|
||||||
|
|
||||||
@Getter(onMethod_ = {@Input, @Optional})
|
@Input
|
||||||
private final Property<String> mainClass;
|
@Optional
|
||||||
|
public abstract Property<String> getMainClass();
|
||||||
|
|
||||||
@Getter(onMethod_ = {@Input, @Optional})
|
@Input
|
||||||
private final Property<String> mainModule;
|
@Optional
|
||||||
|
public abstract Property<String> getMainModule();
|
||||||
|
|
||||||
private final Properties javaAgents = new Properties();
|
private final Properties javaAgents = new Properties();
|
||||||
|
|
||||||
@Getter(onMethod_ = {@Input})
|
@Input
|
||||||
private final Map<String, String> systemProperties = new TreeMap<>();
|
public abstract MapProperty<String, String> getSystemProperties();
|
||||||
|
|
||||||
@Getter(onMethod_ = {@Input})
|
@Input
|
||||||
private final ListProperty<String> extraClasspath;
|
public abstract ListProperty<String> getExtraClasspath();
|
||||||
|
|
||||||
private final org.gradle.api.java.archives.Manifest manifest;
|
private final org.gradle.api.java.archives.Manifest manifest;
|
||||||
|
|
||||||
@@ -128,10 +134,6 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
javaAgents.put(className, args);
|
javaAgents.put(className, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void systemProperty(String key, String value) {
|
|
||||||
systemProperties.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void includeLibraries(Object... files) {
|
public void includeLibraries(Object... files) {
|
||||||
into(Constants.LIBRARIES_FOLDER, (copySpec) -> copySpec.from(files));
|
into(Constants.LIBRARIES_FOLDER, (copySpec) -> copySpec.from(files));
|
||||||
}
|
}
|
||||||
@@ -148,23 +150,21 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
}
|
}
|
||||||
getInputs().files(extractLauncherTaskProvider);
|
getInputs().files(extractLauncherTaskProvider);
|
||||||
|
|
||||||
setGroup("build");
|
setGroup(BasePlugin.BUILD_GROUP);
|
||||||
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);
|
||||||
getDestinationDirectory().set(basePluginExtension.getDistsDirectory());
|
getDestinationDirectory().set(basePluginExtension.getLibsDirectory());
|
||||||
getArchiveBaseName().convention(getProject().getName());
|
getArchiveBaseName().convention(getProject().getName());
|
||||||
getArchiveExtension().convention("jar");
|
getArchiveExtension().convention("jar");
|
||||||
getArchiveVersion().convention(getProject().getVersion().toString());
|
getArchiveVersion().convention(getProject().getVersion().toString());
|
||||||
getArchiveAppendix().convention("envelope");
|
getArchiveAppendix().convention(DEFAULT_ARCHIVE_APPENDIX);
|
||||||
|
|
||||||
manifest = new DefaultManifest(fileResolver);
|
manifest = new DefaultManifest(fileResolver);
|
||||||
mainClass = objects.property(String.class);
|
getSystemProperties().convention(new TreeMap<>());
|
||||||
mainModule = objects.property(String.class);
|
|
||||||
extraClasspath = objects.listProperty(String.class);
|
|
||||||
JavaApplication javaApplication = getProject().getExtensions().findByType(JavaApplication.class);
|
JavaApplication javaApplication = getProject().getExtensions().findByType(JavaApplication.class);
|
||||||
if(!Objects.isNull(javaApplication)) {
|
if(!Objects.isNull(javaApplication)) {
|
||||||
mainClass.convention(javaApplication.getMainClass());
|
getMainClass().convention(javaApplication.getMainClass());
|
||||||
mainModule.convention(javaApplication.getMainModule());
|
getMainModule().convention(javaApplication.getMainModule());
|
||||||
}
|
}
|
||||||
from(getProject().tarTree(extractLauncherTaskProvider.map(ExtractLauncherTask::getLauncherTar)), copySpec -> exclude(JarFile.MANIFEST_NAME));
|
from(getProject().tarTree(extractLauncherTaskProvider.map(ExtractLauncherTask::getLauncherTar)), copySpec -> exclude(JarFile.MANIFEST_NAME));
|
||||||
}
|
}
|
||||||
@@ -292,15 +292,18 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
mainAttributes.put(new Attributes.Name("Can-Redefine-Classes"), "true");
|
mainAttributes.put(new Attributes.Name("Can-Redefine-Classes"), "true");
|
||||||
mainAttributes.put(new Attributes.Name("Can-Retransform-Classes"), "true");
|
mainAttributes.put(new Attributes.Name("Can-Retransform-Classes"), "true");
|
||||||
String separator = "" + Constants.EXTRA_CLASSPATH_ENTRY_SEPARATOR;
|
String separator = "" + Constants.EXTRA_CLASSPATH_ENTRY_SEPARATOR;
|
||||||
String extraClasspath = EnvelopeJarTask.this.extraClasspath.get().stream()
|
ListProperty<String> extraClasspath = EnvelopeJarTask.this.getExtraClasspath();
|
||||||
.map(it -> it.replace(separator, separator + separator)
|
if(extraClasspath.isPresent()) {
|
||||||
).collect(Collectors.joining(separator));
|
String extraClasspathString = extraClasspath.get().stream()
|
||||||
mainAttributes.put(new Attributes.Name(Constants.ManifestAttributes.EXTRA_CLASSPATH), extraClasspath);
|
.map(it -> it.replace(separator, separator + separator)
|
||||||
if(mainClass.isPresent()) {
|
).collect(Collectors.joining(separator));
|
||||||
mainAttributes.putValue(Constants.ManifestAttributes.MAIN_CLASS, mainClass.get());
|
mainAttributes.put(new Attributes.Name(Constants.ManifestAttributes.EXTRA_CLASSPATH), extraClasspathString);
|
||||||
}
|
}
|
||||||
if(mainModule.isPresent()) {
|
if(getMainClass().isPresent()) {
|
||||||
mainAttributes.putValue(Constants.ManifestAttributes.MAIN_MODULE, mainModule.get());
|
mainAttributes.putValue(Constants.ManifestAttributes.MAIN_CLASS, getMainClass().get());
|
||||||
|
}
|
||||||
|
if(getMainModule().isPresent()) {
|
||||||
|
mainAttributes.putValue(Constants.ManifestAttributes.MAIN_MODULE, getMainModule().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
@@ -344,7 +347,7 @@ public class EnvelopeJarTask extends AbstractArchiveTask {
|
|||||||
zipEntry.setMethod(ZipEntry.DEFLATED);
|
zipEntry.setMethod(ZipEntry.DEFLATED);
|
||||||
zipOutputStream.putNextEntry(zipEntry);
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
for(Map.Entry<String, String> entry : systemProperties.entrySet()) {
|
for(Map.Entry<String, String> entry : getSystemProperties().get().entrySet()) {
|
||||||
props.setProperty(entry.getKey(), entry.getValue());
|
props.setProperty(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
props.store(zipOutputStream, null);
|
props.store(zipOutputStream, null);
|
||||||
|
@@ -10,10 +10,14 @@ import org.gradle.api.tasks.JavaExec;
|
|||||||
import org.gradle.api.tasks.bundling.Jar;
|
import org.gradle.api.tasks.bundling.Jar;
|
||||||
|
|
||||||
public class EnvelopePlugin implements Plugin<Project> {
|
public class EnvelopePlugin implements Plugin<Project> {
|
||||||
|
|
||||||
|
public static final String ENVELOPE_GROUP_NAME = " envelope";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Project project) {
|
public void apply(Project project) {
|
||||||
|
project.getPluginManager().apply(JavaPlugin.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(ENVELOPE_GROUP_NAME);
|
||||||
t.setDescription("Package the application in a single executable jar file");
|
t.setDescription("Package the application in a single executable jar file");
|
||||||
t.includeLibraries(project.getConfigurations().named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
|
t.includeLibraries(project.getConfigurations().named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
|
||||||
t.includeLibraries(project.getTasks().named(JavaPlugin.JAR_TASK_NAME, Jar.class));
|
t.includeLibraries(project.getTasks().named(JavaPlugin.JAR_TASK_NAME, Jar.class));
|
||||||
@@ -23,7 +27,7 @@ public class EnvelopePlugin implements Plugin<Project> {
|
|||||||
});
|
});
|
||||||
Provider<JavaExec> envelopeRunTaskProvider = project.getTasks().register("envelopeRun", JavaExec.class, t -> {
|
Provider<JavaExec> envelopeRunTaskProvider = project.getTasks().register("envelopeRun", JavaExec.class, t -> {
|
||||||
t.getInputs().files(envelopeJarTaskProvider);
|
t.getInputs().files(envelopeJarTaskProvider);
|
||||||
t.setGroup("envelope");
|
t.setGroup(ENVELOPE_GROUP_NAME);
|
||||||
t.setDescription("Run the application in the envelope jar");
|
t.setDescription("Run the application in the envelope jar");
|
||||||
t.classpath(envelopeJarTaskProvider);
|
t.classpath(envelopeJarTaskProvider);
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user