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 libs = [:]
|
||||||
def json = [
|
def json = [
|
||||||
_comment_: launcherJson.comment,
|
_comment_: launcherJson.comment,
|
||||||
|
spec: 0,
|
||||||
profile: project.name,
|
profile: project.name,
|
||||||
version: launcherJson.id,
|
version: launcherJson.id,
|
||||||
json: '/version.json',
|
json: '/version.json',
|
||||||
|
|
|
@ -33,7 +33,6 @@ import static net.minecraftforge.fml.Logging.LOADING;
|
||||||
|
|
||||||
public class ModLoadingClassLoader extends SecureClassLoader
|
public class ModLoadingClassLoader extends SecureClassLoader
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -50,6 +49,18 @@ public class ModLoadingClassLoader extends SecureClassLoader
|
||||||
return super.getResource(name);
|
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
|
@Override
|
||||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
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);
|
throw new ClassNotFoundException("Failed to load class file " + classResource + " for "+ className, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else if(getParent() != null) {
|
||||||
getParent().loadClass(name);
|
getParent().loadClass(name);
|
||||||
}
|
}
|
||||||
throw new ClassNotFoundException("Failed to find class file "+ className);
|
throw new ClassNotFoundException("Failed to find class file "+ className);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package net.minecraftforge.userdev;
|
package net.minecraftforge.userdev;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
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.IModLocator;
|
||||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
@ -27,10 +28,16 @@ import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.channels.SeekableByteChannel;
|
||||||
import java.nio.file.Path;
|
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.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
|
@ -88,7 +95,16 @@ public class ClasspathLocator implements IModLocator
|
||||||
if (path.length < 1) {
|
if (path.length < 1) {
|
||||||
throw new IllegalArgumentException("Missing path");
|
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
|
@Override
|
||||||
|
@ -96,22 +112,7 @@ public class ClasspathLocator implements IModLocator
|
||||||
LOGGER.debug(SCAN,"Scanning classpath");
|
LOGGER.debug(SCAN,"Scanning classpath");
|
||||||
|
|
||||||
Path filePath = modFile.getFilePath();
|
Path filePath = modFile.getFilePath();
|
||||||
|
Path scanPath = getClassesPath(filePath);
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
try (Stream<Path> files = Files.find(scanPath, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
|
try (Stream<Path> files = Files.find(scanPath, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
|
||||||
files.forEach(pathConsumer);
|
files.forEach(pathConsumer);
|
||||||
|
@ -121,6 +122,26 @@ public class ClasspathLocator implements IModLocator
|
||||||
LOGGER.debug(SCAN,"Classpath scan complete");
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue