Jump to content

LinkageError when trying to add capability to ItemStack


Silvertide

Recommended Posts

I've been struggling with this error for a while now. I am trying to add a simple capability to an ItemStack, a String owner field. I tracked down the error message to this function:
 

    @SubscribeEvent
    public static void onAttachCapabilitiesItemStack(AttachCapabilitiesEvent<ItemStack> event) {
        ItemStack stack = event.getObject();
        if(!stack.getCapability(ItemOwnerProvider.ITEM_OWNER).isPresent()) {
            LOGGER.info("Trying to attach capabilites to: " + stack.getDisplayName());
            event.addCapability(new ResourceLocation(Artifactory.MOD_ID, "properties"), new ItemOwnerProvider());
        }
    }

Specifically the line: event.addCapability(new ResourceLocation(MyMod.MOD_ID, "properties"), new ItemOwnerProvider());

I am getting the error:

Caused by: java.lang.LinkageError: loader constraint violation: loader 'MC-BOOTSTRAP' @1ebd319f wants to load interface org.apache.logging.log4j.util.MessageSupplier. (org.apache.logging.log4j.util.MessageSupplier is in module [email protected] of loader 'MC-BOOTSTRAP' @1ebd319f, parent loader 'bootstrap')

 

In a different mod I am doing exactly the same code in almost every way except to a player and it works just fine when subclassing <Entity> and attaching a capability to the player.

Any help would be greatly appreciated! An example of a mod repo that has ItemStack capabilities is a huge bonus! Thanks!

 

Link to comment
Share on other sites

Even more specifically, this line of code in the if statement causes that error:

!stack.getCapability(ItemOwnerProvider.ITEM_OWNER).isPresent()

For reference here is my ItemOwnerProvider:


public class ItemOwnerProvider implements ICapabilityProvider, INBTSerializable<CompoundTag> {
    public static Capability<ItemOwner> ITEM_OWNER =
            CapabilityManager.get(new CapabilityToken<ItemOwner>() { });

    private ItemOwner owner = null;
    private final LazyOptional<ItemOwner> optional = LazyOptional.of(this::getOrCreateItemOwner);

    private ItemOwner getOrCreateItemOwner() {
        if(this.owner == null){
            this.owner = new ItemOwner();
        }

        return this.owner;
    }

    @Override
    public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        if(cap == ITEM_OWNER) {
            return optional.cast();
        }

        return LazyOptional.empty();
    }

    @Override
    public CompoundTag serializeNBT() {
        CompoundTag nbt = new CompoundTag();
        getOrCreateItemOwner().saveNBTData(nbt);
        return nbt;
    }

    @Override
    public void deserializeNBT(CompoundTag nbt) {
        getOrCreateItemOwner().loadNBTData(nbt);
    }
}

and here is my ItemOwner:
 

public class ItemOwner {
    private String owner;

    public String getOwner() {
        return this.owner;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

    public void copyFrom(ItemOwner source) {
        this.owner = source.getOwner();
    }

    public void saveNBTData(CompoundTag nbt) {
        nbt.putString("mymod_owner", this.owner);
    }

    public void loadNBTData(CompoundTag nbt) {
        this.owner = nbt.getString("mymod_owner");
    }

 

Link to comment
Share on other sites

https://javadoc.scijava.org/Java6/java/lang/LinkageError.html

The usual cause is you compiled over a different version and the api changed.

But, you can also get this error when the same jar/version is loaded by different classloaders. This leads to 2 different classes even if they are the same bytecode.

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

Do you have any advice for troubleshooting this? I have 2 identical projects with as far as I can tell all the same settings and packages and dependencies. One of them the Player capabilities using almost this same implementation works fine. In the other it errors out.

Link to comment
Share on other sites

The class that gives the error: org.apache.logging.log4j.util.MessageSupplier

 

e.g. compile over version 1

public class ClassFromLibrary implements A {}

public class MyClass extends ClassFromLibrary {}

runtime is over version 2

public class ClassFromLibrary implements B {} // ClassFromLibrary no longer implements A which breaks MyClass

 

As I said above, it could also be a classloading issue where runtime is still over A but from different classloaders.

public class ClassFromLibrary {
   public void consume(A a) {} // A from classloader1
}
public class MyClass implements A {} // A from classloader2

new ClassFromLibrary().consume(new MyClass()); // Error not the same A

 

Linkage errors are usually a bit more subtle than the examples above.

 

But, since you don't show the full error, debug.log, your build file or any other way for me to see what is really going on,

I can only give you a general explanation of the error under the assumption that it is enough for you to debug the problem for yourself.

 

As I have said many times in this forum.

If you want help, you need to provide all the information. Not code snippets out of context or truncated error messages.

Otherwise unless the problem is immediately obvious, you will likely just get ignored.

Something I almost did with your original question since it is a java question not a forge question anyway.

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

The error appears to be at this line of code:

https://github.com/MinecraftForge/EventBus/blob/84663719be842aedaddabf9cd8d46a2450959c9d/src/main/java/net/minecraftforge/eventbus/EventBus.java#L329

Where it is trying to use a lambda expression to create a log4j MessageSupplier and for some reason this is causing the linkage error?

The actual error is not very informative about why there is a linkage error.

 

I don't see any mention of log4j in your build so it doesn't look like you are downloading a conflicting version? Or any other dependency that might transitively do that.

If you run the gradle build with --debug in amongst all the other rubbish, you should be able to see the command line used to start minecraft.

This should say where it is getting log4j from and whether there might be more than one on the classpath or something.

 

I assume you are actually using the gradle build and not some IDE launch configuration?

 

Obviously, your attach capabilities is throwing an error for it to reach that error handler. But then it crashes trying to report the error.

I tried deliberately, throwing an exception from a similar event handler and I don't see any problem with reporting the error.

 

Beyond that, you are going to need to put your project on github to see if we can reproduce the problem using it.

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

It seems like its something to do with the ItemStack implementation. When I attach this capability to a player instead
 

    @SubscribeEvent
    public static void onAttachCapabilitiesItemStack(AttachCapabilitiesEvent<Entity> event) {
        if(event.getObject() instanceof Player){
            Player player = (Player) event.getObject();
            if(!player.getCapability(ItemOwner.INSTANCE).isPresent()) {
                LOGGER.info("Trying to attach capabilites to: " + player.getStringUUID());
                ItemOwnerAttacher.attach(event);
            }
        }
    }

It works just fine.

Link to comment
Share on other sites

The issue is with you calling getCapability() from inside the AttachCapabilities.

That sends it into recursive death.

Quote

      at net.minecraftforge.common.capabilities.ICapabilityProvider.getCapability(ICapabilityProvider.java:33) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at com.silvertide.artifactory.events.EventHandler.onAttachCapabilitiesItemStack(EventHandler.java:84) ~[%23188!/:?] {re:classloading}
        at com.silvertide.artifactory.events.__EventHandler_onAttachCapabilitiesItemStack_AttachCapabilitiesEvent.invoke(.dynamic) ~[%23188!/:?] {re:classloading,pl:eventbus:B}
        at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:73) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.eventbus.EventBus.post(EventBus.java:315) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.eventbus.EventBus.post(EventBus.java:296) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:520) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:514) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.doGatherCapabilities(CapabilityProvider.java:72) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.getCapabilities(CapabilityProvider.java:87) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.getCapability(CapabilityProvider.java:182) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.ICapabilityProvider.getCapability(ICapabilityProvider.java:33) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at com.silvertide.artifactory.events.EventHandler.onAttachCapabilitiesItemStack(EventHandler.java:84) ~[%23188!/:?] {re:classloading}
        at com.silvertide.artifactory.events.__EventHandler_onAttachCapabilitiesItemStack_AttachCapabilitiesEvent.invoke(.dynamic) ~[%23188!/:?] {re:classloading,pl:eventbus:B}
        at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:73) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.eventbus.EventBus.post(EventBus.java:315) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.eventbus.EventBus.post(EventBus.java:296) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:520) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:514) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.doGatherCapabilities(CapabilityProvider.java:72) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.getCapabilities(CapabilityProvider.java:87) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.getCapability(CapabilityProvider.java:182) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.ICapabilityProvider.getCapability(ICapabilityProvider.java:33) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at com.silvertide.artifactory.events.EventHandler.onAttachCapabilitiesItemStack(EventHandler.java:84) ~[%23188!/:?] {re:classloading}
        at com.silvertide.artifactory.events.__EventHandler_onAttachCapabilitiesItemStack_AttachCapabilitiesEvent.invoke(.dynamic) ~[%23188!/:?] {re:classloading,pl:eventbus:B}
        at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:73) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.eventbus.EventBus.post(EventBus.java:315) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.eventbus.EventBus.post(EventBus.java:296) ~[eventbus-6.0.3.jar%23107!/:?] {}
        at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:520) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:514) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.doGatherCapabilities(CapabilityProvider.java:72) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.getCapabilities(CapabilityProvider.java:87) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.CapabilityProvider.getCapability(CapabilityProvider.java:182) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at net.minecraftforge.common.capabilities.ICapabilityProvider.getCapability(ICapabilityProvider.java:33) ~[forge-1.19.2-43.2.0_mapped_official_1.19.2.jar%23182%23189!/:?] {re:classloading}
        at com.silvertide.artifactory.events.EventHandler.onAttachCapabilitiesItemStack(EventHandler.java:84) ~[%23188!/:?] {re:classloading}
        at com.silvertide.artifactory.events.__EventHandler_onAttachCapabilitiesItemStack_AttachCapabilitiesEvent.invoke(.dynamic) ~[%23188!/:?] {re:classloading,pl:eventbus:B}

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

The problem with doing what you are trying to do is discussed here:

https://github.com/MinecraftForge/MinecraftForge/pull/8744

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

Hmm okay, I gave that a read and it's still not super clear. Unfortunate that that is still an open PR and hasn't been changed yet. I guess I'll try to get this working now then go back and fix it later. 

 

Edited by Silvertide
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.