Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ public List<ClassProcessor> transformersFor(Type classDesc, boolean isEmpty, Pro
return out;
}

public void link(Function<ProcessorName, BytecodeProvider> bytecodeProviderLookup) {
public void link(Function<ProcessorName, BytecodeProvider> bytecodeProviderLookup, ClassLoader parentClassLoader) {
if (linked) {
throw new IllegalStateException("This set of class processors is already linked.");
}
linked = true;

for (var processor : sortedProcessors) {
var context = new ClassProcessor.LinkContext(processors, bytecodeProviderLookup.apply(processor.name()));
var context = new ClassProcessor.LinkContext(processors, bytecodeProviderLookup.apply(processor.name()), parentClassLoader);
processor.link(context);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public TransformingClassLoader(ClassProcessorSet classProcessorSet, ClassProcess
super("TRANSFORMER", configuration, parentLayers, parentClassLoader);
this.classTransformer = new ClassTransformer(classProcessorSet, auditTrail);
// The state of this class has to be set up fully before the processors are linked
classProcessorSet.link(processorName -> className -> buildTransformedClassNodeFor(className, processorName));
classProcessorSet.link(processorName -> className -> buildTransformedClassNodeFor(className, processorName), parentClassLoader);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@

import java.net.URL;
import net.neoforged.fml.loading.FMLLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.service.IClassProvider;

/**
* Class provider for use under ModLauncher
*/
class FMLClassProvider implements IClassProvider {
FMLClassProvider() {}
private static final Logger LOGGER = LogManager.getLogger();

private final ClassLoader pluginClassLoader;

FMLClassProvider(ClassLoader pluginClassLoader) {
this.pluginClassLoader = pluginClassLoader;
}

@Override
@Deprecated
Expand All @@ -23,12 +31,26 @@ public URL[] getClassPath() {

@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
return Class.forName(name, true, FMLLoader.getCurrent().getCurrentClassLoader());
try {
return Class.forName(name, true, pluginClassLoader);
} catch (ClassNotFoundException e) {
warnOnDeprecatedTclPluginLoad(name);
return Class.forName(name, true, FMLLoader.getCurrent().getCurrentClassLoader());
}
}

@Override
public Class<?> findClass(String name, boolean initialize) throws ClassNotFoundException {
return Class.forName(name, initialize, FMLLoader.getCurrent().getCurrentClassLoader());
try {
return Class.forName(name, initialize, pluginClassLoader);
} catch (ClassNotFoundException e) {
warnOnDeprecatedTclPluginLoad(name);
return Class.forName(name, initialize, FMLLoader.getCurrent().getCurrentClassLoader());
}
}

private static void warnOnDeprecatedTclPluginLoad(String name) {
LOGGER.error("Mixin attempted to load class {} from the transforming classloader. This behavior is deprecated and may not continue to work; mixin config plugins should be provided from FMLModType=LIBRARY jars instead.", name);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public FMLMixinClassProcessor(FMLMixinService service) {
@Override
public void link(LinkContext context) {
this.service.setBytecodeProvider(new FMLClassBytecodeProvider(context.bytecodeProvider(), this));
this.service.setClassProvider(new FMLClassProvider(context.pluginClassLoader()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public void setBytecodeProvider(@Nullable IClassBytecodeProvider bytecodeProvide
this.bytecodeProvider = bytecodeProvider;
}

public void setClassProvider(@Nullable IClassProvider classProvider) {
this.classProvider = classProvider;
}

@Override
public void offer(IMixinInternal internal) {
if (internal instanceof IMixinTransformerFactory mixinTransformerFactory) {
Expand Down Expand Up @@ -136,15 +140,15 @@ public boolean isValid() {
@Override
public IClassProvider getClassProvider() {
if (this.classProvider == null) {
this.classProvider = new FMLClassProvider();
throw new IllegalStateException("Service initialisation incomplete, FMLMixinClassProcessor has not yet been linked");
}
return this.classProvider;
}

@Override
public IClassBytecodeProvider getBytecodeProvider() {
if (this.bytecodeProvider == null) {
throw new IllegalStateException("Service initialisation incomplete, launch plugin was not created");
throw new IllegalStateException("Service initialisation incomplete, FMLMixinClassProcessor has not yet been linked");
}
return this.bytecodeProvider;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,14 @@ record AfterProcessingContext(Type type) {
* The context provided to {@linkplain ClassProcessor class processors}
* when they are linked with a bytecode source.
*
* @param processors an immutable map of the processors that are being linked. The maps iteration order is the order in which the processors will be applied
* @param bytecodeProvider a provider to access class bytecode for other classes than the class that is being transformed
* @param processors an immutable map of the processors that are being linked. The maps iteration order is the order in which the processors will be applied
* @param bytecodeProvider a provider to access class bytecode for other classes than the class that is being transformed
* @param pluginClassLoader provides access to the classloader before the transforming classloader, for use in safely loading classes
*/
record LinkContext(
@Unmodifiable SequencedMap<ProcessorName, ClassProcessor> processors,
BytecodeProvider bytecodeProvider) {
BytecodeProvider bytecodeProvider,
ClassLoader pluginClassLoader) {
@ApiStatus.Internal
public LinkContext {}
}
Expand Down
Loading