Skip to content
This repository has been archived by the owner on Aug 8, 2024. It is now read-only.

Commit

Permalink
feat(LibraryLoader): Add support to relocate dependencies in order to…
Browse files Browse the repository at this point in the history
… prevent conflicts
  • Loading branch information
GeorgeV220 committed Jan 29, 2024
1 parent f88f5b8 commit 2799777
Showing 1 changed file with 72 additions and 1 deletion.
73 changes: 72 additions & 1 deletion src/main/java/com/georgev22/api/libraryloader/LibraryLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import com.georgev22.api.libraryloader.annotations.MavenLibrary;
import com.georgev22.api.libraryloader.exceptions.InvalidDependencyException;
import com.georgev22.api.libraryloader.exceptions.UnknownDependencyException;
import me.lucko.jarrelocator.JarRelocator;
import me.lucko.jarrelocator.Relocation;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnmodifiableView;
Expand All @@ -39,6 +41,8 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -204,6 +208,20 @@ public void load(String groupId, String artifactId, String version, String repoU
load(new Dependency(groupId, artifactId, version, repoUrl), pathCheck);
}

/**
* Loads a list of dependencies with the specified path check.
*
* @param dependencies the list of dependencies to load
* @param pathCheck flag indicating whether to check if the dependencies are already in the class path
* @throws InvalidDependencyException if a dependency is already loaded or in the class path
* @throws UnknownDependencyException if a dependency cannot be downloaded or loaded
*/
public void load(@NotNull List<Dependency> dependencies, boolean pathCheck) throws InvalidDependencyException, UnknownDependencyException {
for (Dependency d : dependencies) {
load(d, pathCheck);
}
}

/**
* Loads a dependency specified by the Dependency object.
*
Expand Down Expand Up @@ -238,8 +256,24 @@ public void load(@NotNull Dependency d, boolean pathCheck) throws InvalidDepende
logger.info("Dependency '" + name + "' does not exist in the libraries folder. Attempting to download...");
URL url = d.url();

RelocatedDependency relocatedDependency = d instanceof RelocatedDependency ? (RelocatedDependency) d : null;

try (InputStream is = url.openStream()) {
Files.copy(is, saveLocation.toPath());
if (relocatedDependency != null) {
Path tempFilePath = Files.createTempFile(relocatedDependency.artifactId + "-" + relocatedDependency.version, ".tmp");

Files.copy(is, tempFilePath, StandardCopyOption.REPLACE_EXISTING);

JarRelocator relocator = new JarRelocator(tempFilePath.toFile(), saveLocation, relocatedDependency.getRelocations());

try {
relocator.run();
} catch (IOException e) {
throw new UnknownDependencyException(e, "Unable to relocate" + d + "' dependency.");
}
} else {
Files.copy(is, saveLocation.toPath());
}
}

} catch (IOException e) {
Expand Down Expand Up @@ -430,6 +464,43 @@ public boolean equals(Object o) {
}
}

/**
* Represents a relocated dependency with the specified group ID, artifact ID, version, repository URL,
* and a list of relocations for class relocation during loading.
*/
@NotNull
public static class RelocatedDependency extends Dependency {

/**
* The list of relocations for class relocation during loading.
*/
private final List<Relocation> relocations;

/**
* Constructs a new RelocatedDependency with the given group ID, artifact ID, version,
* repository URL, and a list of relocations for class relocation.
*
* @param groupId the group ID of the dependency
* @param artifactId the artifact ID of the dependency
* @param version the version of the dependency
* @param repoUrl the URL of the repository where the dependency is hosted
* @param relocations the list of relocations for class relocation
*/
public RelocatedDependency(String groupId, String artifactId, String version, String repoUrl, List<Relocation> relocations) {
super(groupId, artifactId, version, repoUrl);
this.relocations = notNull("relocations", relocations);
}

/**
* Returns the list of relocations for class relocation during loading.
*
* @return the list of relocations
*/
public List<Relocation> getRelocations() {
return relocations;
}
}

@Contract(pure = true)
@Override
public @NotNull String toString() {
Expand Down

0 comments on commit 2799777

Please sign in to comment.