This commit is contained in:
13
jdeps/build.gradle
Normal file
13
jdeps/build.gradle
Normal file
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
id 'java-gradle-plugin'
|
||||
}
|
||||
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("JdepsPlugin") {
|
||||
id = 'net.woggioni.gradle.jdeps'
|
||||
implementationClass = "net.woggioni.gradle.jdeps.JdepsPlugin"
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
package net.woggioni.gradle.jdeps;
|
||||
|
||||
public class Constants {
|
||||
public static final String JDEPS_TASK_GROUP = "jdeps";
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package net.woggioni.gradle.jdeps;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.plugins.JavaLibraryPlugin;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.TaskContainer;
|
||||
|
||||
public class JdepsPlugin implements Plugin<Project> {
|
||||
public static final String JDEPS_TASK_NAME = "jdeps";
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPluginManager().apply(JavaLibraryPlugin.class);
|
||||
TaskContainer tasks = project.getTasks();
|
||||
Provider<JdepsTask> jdepsTaskProvider = tasks.register(JDEPS_TASK_NAME, JdepsTask.class, jdepsTask -> {
|
||||
ConfigurationContainer configurations = project.getConfigurations();
|
||||
FileCollection classpath = project.files(configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
|
||||
jdepsTask.getClasspath().set(classpath);
|
||||
jdepsTask.getArchives().set(project.files(tasks.named(JavaPlugin.JAR_TASK_NAME)));
|
||||
});
|
||||
}
|
||||
}
|
209
jdeps/src/main/java/net/woggioni/gradle/jdeps/JdepsTask.java
Normal file
209
jdeps/src/main/java/net/woggioni/gradle/jdeps/JdepsTask.java
Normal file
@@ -0,0 +1,209 @@
|
||||
package net.woggioni.gradle.jdeps;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.file.ProjectLayout;
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.Logging;
|
||||
import org.gradle.api.plugins.BasePluginExtension;
|
||||
import org.gradle.api.plugins.ExtensionContainer;
|
||||
import org.gradle.api.plugins.JavaApplication;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.reporting.ReportingExtension;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
import org.gradle.api.tasks.Exec;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputDirectory;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.internal.jvm.JavaModuleDetector;
|
||||
import org.gradle.jvm.toolchain.JavaToolchainService;
|
||||
import org.gradle.jvm.toolchain.JavaToolchainSpec;
|
||||
import org.gradle.jvm.toolchain.internal.DefaultToolchainSpec;
|
||||
import org.gradle.process.CommandLineArgumentProvider;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.woggioni.gradle.jdeps.Constants.JDEPS_TASK_GROUP;
|
||||
|
||||
public abstract class JdepsTask extends Exec {
|
||||
|
||||
private final JavaToolchainSpec toolchain;
|
||||
|
||||
public JavaToolchainSpec toolchain(Action<? super JavaToolchainSpec> action) {
|
||||
action.execute(toolchain);
|
||||
return toolchain;
|
||||
}
|
||||
|
||||
@Classpath
|
||||
public abstract Property<FileCollection> getClasspath();
|
||||
|
||||
@Classpath
|
||||
public abstract Property<FileCollection> getArchives();
|
||||
|
||||
@InputDirectory
|
||||
public abstract DirectoryProperty getJavaHome();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getMainClass();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getMainModule();
|
||||
|
||||
@Input
|
||||
public abstract ListProperty<String> getAdditionalModules();
|
||||
|
||||
@Inject
|
||||
protected abstract JavaModuleDetector getJavaModuleDetector();
|
||||
|
||||
@OutputDirectory
|
||||
public abstract DirectoryProperty getOutputDir();
|
||||
|
||||
@Optional
|
||||
@OutputDirectory
|
||||
public abstract DirectoryProperty getDotOutput();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<Integer> getJavaRelease();
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getRecursive();
|
||||
|
||||
private static final Logger log = Logging.getLogger(JdepsTask.class);
|
||||
|
||||
public JdepsTask() {
|
||||
Project project = getProject();
|
||||
setGroup(JDEPS_TASK_GROUP);
|
||||
setDescription(
|
||||
"Generates a custom Java runtime image that contains only the platform modules" +
|
||||
" that are required for a given application");
|
||||
ExtensionContainer ext = project.getExtensions();
|
||||
JavaApplication javaApplication = ext.findByType(JavaApplication.class);
|
||||
if (!Objects.isNull(javaApplication)) {
|
||||
getMainClass().convention(javaApplication.getMainClass());
|
||||
getMainModule().convention(javaApplication.getMainModule());
|
||||
}
|
||||
getClasspath().convention(project.files());
|
||||
getRecursive().convention(true);
|
||||
ProjectLayout layout = project.getLayout();
|
||||
toolchain = getObjectFactory().newInstance(DefaultToolchainSpec.class);
|
||||
JavaToolchainService javaToolchainService = ext.findByType(JavaToolchainService.class);
|
||||
Provider<Directory> graalHomeDirectoryProvider = javaToolchainService.launcherFor(it -> {
|
||||
it.getLanguageVersion().set(toolchain.getLanguageVersion());
|
||||
it.getVendor().set(toolchain.getVendor());
|
||||
it.getImplementation().set(toolchain.getImplementation());
|
||||
}).map(javaLauncher ->
|
||||
javaLauncher.getMetadata().getInstallationPath()
|
||||
).orElse(layout.dir(project.provider(() -> project.file(System.getProperty("java.home")))));
|
||||
getJavaHome().convention(graalHomeDirectoryProvider);
|
||||
|
||||
getJavaHome().convention(graalHomeDirectoryProvider);
|
||||
getAdditionalModules().convention(new ArrayList<>());
|
||||
|
||||
ReportingExtension reporting = ext.getByType(ReportingExtension.class);
|
||||
|
||||
getOutputDir().convention(
|
||||
reporting.getBaseDirectory()
|
||||
.dir(project.getName() +
|
||||
ofNullable(project.getVersion()).map(it -> "-" + it).orElse(""))
|
||||
);
|
||||
getDotOutput().convention(getOutputDir().dir("graphviz"));
|
||||
Object executableProvider = new Object() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return getJavaHome().get() + "/bin/jdeps";
|
||||
}
|
||||
};
|
||||
executable(executableProvider);
|
||||
CommandLineArgumentProvider argumentProvider = new CommandLineArgumentProvider() {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Iterable<String> asArguments() {
|
||||
List<String> result = new ArrayList<>();
|
||||
JavaModuleDetector javaModuleDetector = getJavaModuleDetector();
|
||||
FileCollection classpath = getClasspath().get();
|
||||
FileCollection mp = javaModuleDetector.inferModulePath(true, classpath);
|
||||
if (!mp.isEmpty()) {
|
||||
result.add("--module-path");
|
||||
result.add(mp.getAsPath());
|
||||
}
|
||||
|
||||
FileCollection cp = classpath.minus(mp);
|
||||
if(!cp.isEmpty()) {
|
||||
result.add("-cp");
|
||||
result.add(cp.getAsPath());
|
||||
}
|
||||
|
||||
List<String> additionalModules = getAdditionalModules().get();
|
||||
if (!additionalModules.isEmpty()) {
|
||||
result.add("--add-modules");
|
||||
final List<String> modules2BeAdded = new ArrayList<>();
|
||||
modules2BeAdded.addAll(additionalModules);
|
||||
if (!modules2BeAdded.isEmpty()) {
|
||||
result.add(String.join(",", modules2BeAdded));
|
||||
}
|
||||
}
|
||||
if (getDotOutput().isPresent()) {
|
||||
result.add("-dotoutput");
|
||||
result.add(getDotOutput().get().getAsFile().toString());
|
||||
}
|
||||
|
||||
if(getRecursive().get()) {
|
||||
result.add("--recursive");
|
||||
} else {
|
||||
result.add("--no-recursive");
|
||||
}
|
||||
|
||||
if (getMainModule().isPresent()) {
|
||||
result.add("-m");
|
||||
result.add(getMainModule().get());
|
||||
}
|
||||
if (getJavaRelease().isPresent()) {
|
||||
result.add("--multi-release");
|
||||
result.add(getJavaRelease().get().toString());
|
||||
}
|
||||
|
||||
for (File archive : getArchives().get()) {
|
||||
result.add(archive.toString());
|
||||
}
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
};
|
||||
getArgumentProviders().add(argumentProvider);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
protected void exec() {
|
||||
Files.walk(getOutputDir().get().getAsFile().toPath())
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.forEach(new Consumer<Path>() {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void accept(Path path) {
|
||||
Files.delete(path);
|
||||
}
|
||||
});
|
||||
super.exec();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user