Fix classloading issues in userdev (and possibly also for things like tests within forgedev) (#5275)
This commit is contained in:
parent
f13465012b
commit
52b6da1759
3 changed files with 54 additions and 21 deletions
|
@ -460,6 +460,7 @@ project(':forge') {
|
|||
def libs = [:]
|
||||
def json = [
|
||||
_comment_: launcherJson.comment,
|
||||
spec: 0,
|
||||
profile: project.name,
|
||||
version: launcherJson.id,
|
||||
json: '/version.json',
|
||||
|
|
|
@ -33,7 +33,6 @@ import static net.minecraftforge.fml.Logging.LOADING;
|
|||
|
||||
public class ModLoadingClassLoader extends SecureClassLoader
|
||||
{
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
static {
|
||||
|
@ -50,6 +49,18 @@ public class ModLoadingClassLoader extends SecureClassLoader
|
|||
return super.getResource(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
|
||||
{
|
||||
final String className = name.replace('.', '/').concat(".class");
|
||||
final Path classResource = FMLLoader.getLoadingModList().findResource(className);
|
||||
if (classResource != null)
|
||||
{
|
||||
return findClass(name);
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
|
@ -65,7 +76,7 @@ public class ModLoadingClassLoader extends SecureClassLoader
|
|||
{
|
||||
throw new ClassNotFoundException("Failed to load class file " + classResource + " for "+ className, e);
|
||||
}
|
||||
} else {
|
||||
} else if(getParent() != null) {
|
||||
getParent().loadClass(name);
|
||||
}
|
||||
throw new ClassNotFoundException("Failed to find class file "+ className);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package net.minecraftforge.userdev;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.IModLocator;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
@ -27,10 +28,16 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.nio.file.attribute.FileAttributeView;
|
||||
import java.nio.file.attribute.UserPrincipalLookupService;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.jar.Manifest;
|
||||
|
@ -88,7 +95,16 @@ public class ClasspathLocator implements IModLocator
|
|||
if (path.length < 1) {
|
||||
throw new IllegalArgumentException("Missing path");
|
||||
}
|
||||
return modFile.getFilePath().resolve(modFile.getFilePath().getFileSystem().getPath(path[0], Arrays.copyOfRange(path, 1, path.length)));
|
||||
|
||||
Path filePath = modFile.getFilePath();
|
||||
Path classesRoot = getClassesPath(filePath);
|
||||
String[] tail = Arrays.copyOfRange(path, 1, path.length);
|
||||
Path classPath = classesRoot.resolve(classesRoot.getFileSystem().getPath(path[0], tail));
|
||||
if(Files.exists(classPath))
|
||||
{
|
||||
return classPath;
|
||||
}
|
||||
return filePath.resolve(filePath.getFileSystem().getPath(path[0], tail));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,22 +112,7 @@ public class ClasspathLocator implements IModLocator
|
|||
LOGGER.debug(SCAN,"Scanning classpath");
|
||||
|
||||
Path filePath = modFile.getFilePath();
|
||||
|
||||
Path scanPath = filePath;
|
||||
|
||||
// Hack 1: When running from within intellij, we get
|
||||
// "out/production/resources" + "out/production/classes"
|
||||
if(filePath.getNameCount() >= 1 && filePath.getName(filePath.getNameCount()-1).toString().equals("resources"))
|
||||
{
|
||||
scanPath = filePath.getParent().resolve("classes");
|
||||
}
|
||||
// Hack 2: When running from gradle, we get
|
||||
// "build/resources/<sourceset>" + "build/classes/<language>/<sourceset>"
|
||||
else if(filePath.getNameCount() >= 2 && filePath.getName(filePath.getNameCount()-2).toString().equals("resources"))
|
||||
{
|
||||
// We'll scan all the subdirectories for languages and sourcesets, hopefully that works...
|
||||
scanPath = filePath.getParent().getParent().resolve("classes");
|
||||
}
|
||||
Path scanPath = getClassesPath(filePath);
|
||||
|
||||
try (Stream<Path> files = Files.find(scanPath, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
|
||||
files.forEach(pathConsumer);
|
||||
|
@ -121,6 +122,26 @@ public class ClasspathLocator implements IModLocator
|
|||
LOGGER.debug(SCAN,"Classpath scan complete");
|
||||
}
|
||||
|
||||
private Path getClassesPath(Path filePath)
|
||||
{
|
||||
Path classesPath = filePath;
|
||||
|
||||
// Hack 1: When running from within intellij, we get
|
||||
// "out/production/resources" + "out/production/classes"
|
||||
if(filePath.getNameCount() >= 1 && filePath.getName(filePath.getNameCount()-1).toString().equals("resources"))
|
||||
{
|
||||
classesPath = filePath.getParent().resolve("classes");
|
||||
}
|
||||
// Hack 2: When running from gradle, we get
|
||||
// "build/resources/<sourceset>" + "build/classes/<language>/<sourceset>"
|
||||
else if(filePath.getNameCount() >= 2 && filePath.getName(filePath.getNameCount()-2).toString().equals("resources"))
|
||||
{
|
||||
// We'll scan all the subdirectories for languages and sourcesets, hopefully that works...
|
||||
classesPath = filePath.getParent().getParent().resolve("classes");
|
||||
}
|
||||
return classesPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue