Skip to content

Commit 4e526b7

Browse files
committed
4.1.0: Use MVNLoader instead of DepDownloader
1 parent 19c75d8 commit 4e526b7

File tree

8 files changed

+22
-146
lines changed

8 files changed

+22
-146
lines changed

api/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ dependencies {
88
implementation "com.googlecode.json-simple:json-simple:$jsonSimpleVersion"
99
implementation "com.google.guava:guava:$guavaVersion"
1010
compileOnly "org.slf4j:slf4j-api:1.7.30"
11-
compile "com.github.egg82:DepDownloader:20373b7f6e"
11+
compile "com.github.egg82:MVNLoader:276fc2165f"
1212
compile "me.lucko:jar-relocator:1.4"
1313
}
1414

Lines changed: 18 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,51 @@
11
package net.playeranalytics.plugin.dependencies;
22

3-
import me.lucko.jarrelocator.JarRelocator;
43
import me.lucko.jarrelocator.Relocation;
54
import net.playeranalytics.plugin.PluginInformation;
6-
import net.playeranalytics.plugin.server.PluginLogger;
7-
import ninja.egg82.maven.Artifact;
8-
import ninja.egg82.maven.Repository;
9-
import ninja.egg82.maven.Scope;
10-
import ninja.egg82.utils.InjectUtil;
11-
import org.xml.sax.SAXException;
5+
import ninja.egg82.mvn.JarBuilder;
6+
import ninja.egg82.mvn.JarInjector;
7+
import ninja.egg82.mvn.classloaders.TransparentInjectableClassLoader;
8+
import org.apache.maven.model.building.ModelBuildingException;
129

13-
import javax.xml.xpath.XPathExpressionException;
1410
import java.io.File;
1511
import java.io.IOException;
16-
import java.io.UncheckedIOException;
17-
import java.lang.reflect.InvocationTargetException;
18-
import java.net.URISyntaxException;
1912
import java.net.URLClassLoader;
20-
import java.nio.file.Files;
21-
import java.util.*;
22-
import java.util.concurrent.*;
13+
import java.util.List;
2314

2415
public class DependencyLoader {
2516

2617
private final URLClassLoader classLoader;
27-
private final PluginLogger pluginLogger;
2818

29-
private final ExecutorService downloadPool = Executors.newWorkStealingPool(Math.max(4, Runtime.getRuntime().availableProcessors() / 2));
30-
private final Set<DependencyAndRelocations> dependencies = new HashSet<>();
31-
private final File dependencyCache;
32-
private final File libraryFolder;
19+
private final JarInjector jarInjector;
3320

34-
public DependencyLoader(URLClassLoader classLoader, PluginLogger pluginLogger, PluginInformation pluginInformation) {
21+
public DependencyLoader(URLClassLoader classLoader, PluginInformation pluginInformation) {
3522
this.classLoader = classLoader;
36-
this.pluginLogger = pluginLogger;
37-
dependencyCache = pluginInformation.getDataDirectory().resolve("dependency_cache").toFile();
38-
libraryFolder = pluginInformation.getDataDirectory().resolve("libraries").toFile();
23+
24+
File dependencyCache = pluginInformation.getDataDirectory().resolve("dep_cache").toFile();
25+
26+
jarInjector = new JarInjector(dependencyCache);
3927
}
4028

4129
public DependencyLoader addDependency(
4230
String repositoryAddress, String group, String artifact, String version,
4331
List<Relocation> relocations
44-
) throws IOException {
32+
) {
4533
try {
46-
Artifact dependency = Artifact.builder(group, artifact, version, dependencyCache, Scope.COMPILE)
47-
.addRepository(Repository.builder(repositoryAddress).build())
48-
.build();
49-
Stack<DependencyAndRelocations> dependencyLookup = new Stack<>();
50-
dependencyLookup.add(new DependencyAndRelocations(dependency, relocations));
51-
while (!dependencyLookup.isEmpty() && dependencyLookup.peek() != null) {
52-
DependencyAndRelocations current = dependencyLookup.pop();
53-
Artifact currentArtifact = current.getArtifact();
54-
if (currentArtifact.getScope() == Scope.COMPILE) {
55-
currentArtifact.getDependencies().stream()
56-
.map(dependencyArtifact ->
57-
new DependencyAndRelocations(dependencyArtifact, relocations))
58-
.forEach(dependencyLookup::add);
59-
dependencies.add(current);
60-
}
34+
jarInjector.addBuilder(new JarBuilder(group, artifact, version, repositoryAddress));
35+
for (Relocation relocation : relocations) {
36+
jarInjector.addRelocation(relocation);
6137
}
62-
} catch (URISyntaxException | XPathExpressionException | SAXException e) {
38+
} catch (ClassCastException e) {
6339
throw new IllegalArgumentException("Incorrect dependency definition", e);
6440
}
6541
return this;
6642
}
6743

68-
public void load() throws IOException {
44+
public void load() throws IOException, ModelBuildingException {
6945
ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
7046
try {
7147
Thread.currentThread().setContextClassLoader(classLoader);
72-
loadDependencies();
48+
jarInjector.inject(new TransparentInjectableClassLoader(classLoader));
7349
} finally {
7450
Thread.currentThread().setContextClassLoader(origClassLoader);
7551
}
@@ -85,99 +61,4 @@ public <T extends Runnable> void executeWithDependencyClassloaderContext(T runna
8561
Thread.currentThread().setContextClassLoader(origClassLoader);
8662
}
8763
}
88-
89-
private void loadDependencies() throws IOException {
90-
List<CompletableFuture<?>> loading = new ArrayList<>();
91-
List<Throwable> downloadErrors = new CopyOnWriteArrayList<>();
92-
for (DependencyAndRelocations dependency : dependencies) {
93-
loading.add(scheduleLoading(downloadErrors, dependency));
94-
}
95-
CompletableFuture.allOf(loading.toArray(new CompletableFuture[0])).join();
96-
shutdownPool(downloadErrors);
97-
98-
if (!downloadErrors.isEmpty()) {
99-
throwError(downloadErrors);
100-
}
101-
}
102-
103-
private CompletableFuture<Void> scheduleLoading(List<Throwable> downloadErrors, DependencyAndRelocations dependency) {
104-
return CompletableFuture.runAsync(() -> {
105-
try {
106-
loadDependency(dependency);
107-
} catch (IOException e) {
108-
throw new UncheckedIOException(e);
109-
}
110-
}, downloadPool).exceptionally(throwable -> {
111-
downloadErrors.add(throwable);
112-
return null;
113-
});
114-
}
115-
116-
private void shutdownPool(List<Throwable> downloadErrors) {
117-
downloadPool.shutdown();
118-
try {
119-
if (!downloadPool.awaitTermination(1, TimeUnit.HOURS)) {
120-
downloadErrors.add(0, new IOException("Download timeout exceeded"));
121-
}
122-
} catch (InterruptedException e) {
123-
Thread.currentThread().interrupt();
124-
}
125-
}
126-
127-
private void throwError(List<Throwable> downloadErrors) throws IOException {
128-
IOException firstError = new IOException("Failed to download all dependencies (see suppressed exceptions for why it failed)");
129-
for (Throwable downloadError : downloadErrors) {
130-
firstError.addSuppressed(downloadError.getCause());
131-
}
132-
throw firstError;
133-
}
134-
135-
private void loadDependency(DependencyAndRelocations toLoad) throws IOException {
136-
Artifact dependency = toLoad.getArtifact();
137-
String artifactCoordinates = dependency.getGroupId() + "-" +
138-
dependency.getArtifactId() + "-" + dependency.getVersion();
139-
Files.createDirectories(libraryFolder.toPath());
140-
File artifactFile = libraryFolder.toPath().resolve(artifactCoordinates + ".jar").toFile();
141-
File relocatedArtifactFile = libraryFolder.toPath().resolve(artifactCoordinates + "-relocated.jar").toFile();
142-
143-
if (!relocatedArtifactFile.exists() && !toLoad.getRelocations().isEmpty()) {
144-
if (!dependency.fileExists(artifactFile)) {
145-
pluginLogger.info("Downloading library: " + dependency.getArtifactId() + "..");
146-
download(dependency, artifactCoordinates, artifactFile);
147-
}
148-
new JarRelocator(artifactFile, relocatedArtifactFile, toLoad.getRelocations()).run();
149-
150-
inject(relocatedArtifactFile);
151-
} else if (relocatedArtifactFile.exists()) {
152-
inject(relocatedArtifactFile);
153-
} else {
154-
if (!dependency.fileExists(artifactFile)) {
155-
pluginLogger.info("Downloading library: " + dependency.getArtifactId() + "..");
156-
download(dependency, artifactCoordinates, artifactFile);
157-
}
158-
159-
inject(artifactFile);
160-
}
161-
}
162-
163-
private void inject(File artifactFile) throws IOException {
164-
try {
165-
InjectUtil.injectFile(artifactFile, classLoader);
166-
} catch (IllegalAccessException | InvocationTargetException e) {
167-
throw new IOException("Failed to download " + artifactFile + ", " + e.getMessage(), e);
168-
}
169-
}
170-
171-
private void download(Artifact dependency, String artifactCoordinates, File artifactFile) throws IOException {
172-
try {
173-
dependency.downloadJar(artifactFile);
174-
} catch (IOException e) {
175-
StringBuilder repositories = new StringBuilder();
176-
for (Repository repository : dependency.getRepositories()) {
177-
repositories.append(" ").append(repository.getURL());
178-
}
179-
pluginLogger.warn("Failed to download " + artifactCoordinates + " from repositories (" + repositories + "), " + e.getMessage());
180-
throw e;
181-
}
182-
}
18364
}

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ plugins {
22
id 'java'
33
}
44
group 'net.playeranalytics'
5-
version '4.0.13'
5+
version '4.1.0'
66

77
allprojects {
88
group 'net.playeranalytics'
9-
version '4.0.13'
9+
version '4.1.0'
1010

1111
ext.version = project.version
1212

1313
compileJava { options.encoding = "UTF-8" }
1414

15-
ext.paperVersion = '1.16.5-R0.1-SNAPSHOT'
15+
ext.paperVersion = '1.16.4-R0.1-SNAPSHOT'
1616
ext.spongeVersion = '7.3.0'
1717
ext.nukkitVersion = '1.0-SNAPSHOT'
1818
ext.bungeecordVersion = '1.16-R0.4'

bukkit/src/main/java/net/playeranalytics/plugin/BukkitPlatformLayer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ public DependencyLoader getDependencyLoader() {
5959
if (dependencyLoader == null) {
6060
dependencyLoader = new DependencyLoader(
6161
(URLClassLoader) getClass().getClassLoader(),
62-
getPluginLogger(),
6362
getPluginInformation()
6463
);
6564
}

bungeecord/src/main/java/net/playeranalytics/plugin/BungeePlatformLayer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public DependencyLoader getDependencyLoader() {
6161
if (dependencyLoader == null) {
6262
dependencyLoader = new DependencyLoader(
6363
(URLClassLoader) getClass().getClassLoader(),
64-
getPluginLogger(),
6564
getPluginInformation()
6665
);
6766
}

nukkit/src/main/java/net/playeranalytics/plugin/NukkitPlatformLayer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public DependencyLoader getDependencyLoader() {
5454
if (dependencyLoader == null) {
5555
dependencyLoader = new DependencyLoader(
5656
(URLClassLoader) getClass().getClassLoader(),
57-
getPluginLogger(),
5857
getPluginInformation()
5958
);
6059
}

sponge/src/main/java/net/playeranalytics/plugin/SpongePlatformLayer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ public DependencyLoader getDependencyLoader() {
5959
if (dependencyLoader == null) {
6060
dependencyLoader = new DependencyLoader(
6161
(URLClassLoader) getClass().getClassLoader(),
62-
getPluginLogger(),
6362
getPluginInformation()
6463
);
6564
}

velocity/src/main/java/net/playeranalytics/plugin/VelocityPlatformLayer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public DependencyLoader getDependencyLoader() {
6464
if (dependencyLoader == null) {
6565
dependencyLoader = new DependencyLoader(
6666
(URLClassLoader) getClass().getClassLoader(),
67-
getPluginLogger(),
6867
getPluginInformation()
6968
);
7069
}

0 commit comments

Comments
 (0)