Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[SOLVED][1.6.4] Stripping external mod interface throws NoClassDefFound

Featured Replies

Posted

I'm using another mod as a referenced library / dependency, and it works fine when run in the development environment. However, after compiling, if I try to run Minecraft with only my mod loaded, the following MyClass throws a no class definition found error, as does the external mod interface class. It of course works fine when run with the other mod also installed.

 

I'm not very familiar with the following annotations, but I was under the impression that it should strip the interface during run-time if the other mod is not found, but leave the rest of the class intact. This is the only class in which I reference this external interface.

// The errors:
Caused by: java.lang.NoClassDefFoundError: modid/package/MyClass
Caused by: java.lang.ClassNotFoundException: mods.external_mod.api.package.IOtherModInterface

@Interface(iface="mods.external_mod.api.ISomeInterface", modid="modid", striprefs = true)
public class MyClass extends VanillaClass implements IOtherModInterface, IMyInterfaces
{
// my code

// external mod API methods
@Method(modid="external_modid")
@Override
public void someMethod() {}

Thanks for whatever help you can give.

public class MyClass extends VanillaClass implements IOtherModInterface, IMyInterfaces

 

And what did you expect it to do if you didn't include IOtherModInterface in your zip?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

  • Author

I was under the impression that

@Interface(iface="mods.external_mod.api.ISomeInterface", modid="modid", striprefs = true)

would strip the interface during run-time if not found. Of course I understand it will throw that error if I don't include the api source, but the whole point is to not require it alongside my mod yet still be able to implement features in the case that the two mods are installed together.

 

Previously I accomplished this by having a second class, MyClass2 extends MyClass1 implements IOtherModInterface, and the only thing it did was implement those interface methods. Then I would assign my items to MyClass2 if the other mod was loaded, otherwise assign them to MyClass1, but I was hoping to find some way around that.

 

I'd appreciate more constructive comments in the future. Cheers.

Did you try with your built jar in game too ?

It is possible that the ModAPITransformer won't start in the dev environment (because deobfuscated and all that).

  • Author

It's working fine in the development environment, but not with the Minecraft launcher. I have the other mod linked as a library in my project, so the mod always loads alongside mine, meaning the class definitions are there, so I'm not sure whether the ModAPITransformer is working or not.

  • Author

Sorry, I still haven't been able to find out why the ModAPITransformer isn't stripping the interface when loading my built mod in the normal Minecraft launcher. Am I just using it incorrectly, or is it not working properly?

 

In the meantime, I'm back to using two classes that are identical except that one implements the other mod's api interface and is only used when that mod is loaded, while the other gets used otherwise. While that works just fine, I'd prefer a more sophisticated approach. If anyone can point me in the right direction, I'd be very grateful.

I made an example, and it worked.

 

Optional removal - found optionals for class com.example.examplemod.TestItem - processing
Optional on com.example.examplemod.TestItem triggered - mod missing battlegear2
Optional removal - interface mods.battlegear2.api.weapons.IBattlegearWeapon removed
Optional removal - interface mods.battlegear2.api.weapons.IBattlegearWeapon - stripping method signature references
Optional removal - interface mods.battlegear2.api.weapons.IBattlegearWeapon - all method signature references 

 

@Optional.Interface(iface = "mods.battlegear2.api.weapons.IBattlegearWeapon", modid = "battlegear2", striprefs = true)
public class TestItem extends Item implements IBattlegearWeapon{
    public TestItem(int id){
        super(id);
        setUnlocalizedName("test:example");
        setTextureName("test:example");
    }
    @Override
    public boolean allowOffhand(ItemStack stack, ItemStack stack2) {
        return false;
    }

    @Override
    public boolean isOffhandHandDual(ItemStack stack) {
        return false;
    }

    @Override
    public boolean offhandAttackEntity(PlayerEventChild.OffhandAttackEvent offhandAttackEvent, ItemStack stack, ItemStack stack2) {
        return false;
    }

    @Override
    public boolean offhandClickAir(PlayerInteractEvent playerInteractEvent, ItemStack stack, ItemStack stack2) {
        return false;
    }

    @Override
    public boolean offhandClickBlock(PlayerInteractEvent playerInteractEvent, ItemStack stack, ItemStack stack2) {
        return false;
    }

    @Override
    public void performPassiveEffects(Side side, ItemStack stack, ItemStack stack2) {

    }

    @Override
    public boolean sheatheOnBack(ItemStack stack) {
        return false;
    }
}

 

Maybe you have a typo somewhere ?

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.