Jump to content

(1.18.2) use jsoup library NoClassDefFoundError


ElTotisPro50

Recommended Posts

Im trying to test jsoup library in minecraft, so, i looked in the page and im suposed to put this in the "dependencies {}"

implementation 'org.jsoup:jsoup:1.15.3'

i did that, built it and it gave me a build successfull, when i try to use the library in game, for example grabbing a song lyrics, it gives me a NoClassDefFoundError

BTW: im grabbing the lyrics when i press a button inside my screen

BTW x2: i added the library in a different project (maven), used the same method for grabbing a song lyric, and it works, so maybe im doing something wrong in build.gradle because is not problem of pressing the button or the screen

 

Crash report: https://pastebin.com/GLHVb0up

build.gradle important stuff (if you need something else from the file tell me):

buildscript {
    repositories {
        maven { url = 'https://maven.minecraftforge.net' }
        maven { url = 'https://maven.parchmentmc.org' }
        mavenCentral()
    }
    dependencies {
        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
        classpath 'org.parchmentmc:librarian:1.+'
    }
}

repositories {
}

dependencies {
    minecraft 'net.minecraftforge:forge:1.18.2-40.1.0'
    implementation 'org.jsoup:jsoup:1.15.3'
}

 

My screen class: 

public class LyricsGathererScreen extends AbstractContainerScreen<LyricsGathererMenu> {

	public static final ResourceLocation TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/gui/lyricsgatherer_gui.png");
	private Button button;
	private EditBox box;
	private Player player;

	public LyricsGathererScreen(LyricsGathererMenu menu, Inventory inv, Component component) {
		super(menu, inv, component);
		this.player = inv.player;
		inventoryLabelY = -1000;
	}

	@Override
	protected void init() {
		super.init();
		int x = (width - imageWidth) / 2;
		int y = (height - imageHeight) / 2;

		this.minecraft.keyboardHandler.setSendRepeatsToGui(true);
		this.box = new EditBox(font, x + 55, y + 14, 76, 15, TextComponent.EMPTY);
		this.box.setCanLoseFocus(false);
		this.box.setTextColor(-1);
		this.box.setTextColorUneditable(-1);
		this.box.setBordered(true);
		this.box.setMaxLength(50);
		this.box.setValue("");
		this.addWidget(this.box);
		this.setInitialFocus(this.box);

		this.button = addRenderableWidget(new Button(x + 55,y + 52,70,20,new TextComponent("Get lyrics"), button -> {
			try {
				if(this.box.getValue().length() < 1) return;
				String test = TotisLyricsGathererUtils.getSongLyrics(this.box.getValue().trim());
				player.sendMessage(new TextComponent(test), player.getUUID());
			} catch(Exception e) {}
		}));
	}

	@Override
	public void removed() {
		super.removed();
		this.minecraft.keyboardHandler.setSendRepeatsToGui(false);
	}

	public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
		if (pKeyCode == 256) {
			this.minecraft.player.closeContainer();
		}
		return !this.box.keyPressed(pKeyCode, pScanCode, pModifiers) && !this.box.canConsumeInput() ? super.keyPressed(pKeyCode, pScanCode, pModifiers) : true;
	}

	@Override
	protected void renderLabels(PoseStack stack, int mouseX, int mouseY) {
		super.renderLabels(stack, mouseX, mouseY);
	}
	
	@Override
	protected void renderBg(PoseStack stack, float partialTick, int mouseX, int mouseY) {
		RenderSystem.setShader(GameRenderer::getPositionTexShader);
        RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
        RenderSystem.setShaderTexture(0, TEXTURE);
        int x = (width - imageWidth) / 2;
        int y = (height - imageHeight) / 2;

        this.blit(stack, x, y, 0, 0, imageWidth, imageHeight); // height - 95
	}
	
	@Override
    public void render(PoseStack pPoseStack, int mouseX, int mouseY, float delta) {
        renderBackground(pPoseStack);
        super.render(pPoseStack, mouseX, mouseY, delta);
		this.renderFg(pPoseStack, mouseX, mouseY, delta);
        renderTooltip(pPoseStack, mouseX, mouseY);
    }

	public void renderFg(PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
		this.box.render(pPoseStack, pMouseX, pMouseY, pPartialTick);
	}
}

 

The helper for find the lyrics (as i said, i used this exact method too for another project and it worked):

public class TotisLyricsGathererUtils {

	private static final String songLyricsURL = "https://www.google.com";
	private static final String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36";
	
	public static String getSongLyrics(String all) throws IOException {
		Document doc = Jsoup.connect(songLyricsURL + "/search?q=" + all.replace(" ", "+").toLowerCase() + "+lyrics").userAgent(userAgent).get();
		
		String title = doc.title();
		title = String.join(" ",title).replace("- Buscar con Google", "");
		
		Element p = doc.select("div.sATSHe").get(0);
		String lyrics = p.text();
		
		lyrics = String.join(" ", lyrics).replace("Letras", "");
		
		String[] parts = lyrics.split("Se produjo un error");
		String realLyrics = parts[0];
		return realLyrics.trim();
	}
}

 

Edited by ElTotisPro50
Link to comment
Share on other sites

The classes won't magically appear inside Minecraft at runtime.

You either need to:

* Make a new mod for JSoup. This is for example what somebody has done for Rhino (a javascript engine). https://www.curseforge.com/minecraft/mc-mods/rhino

* Use a gradle plugin to include the jsoup classes inside your mod jar, e.g. https://github.com/johnrengelman/shadow

 

The second method could give you problems if somebody else does the same thing but a different version of jsoup.

You might use their wrong classes depending upon which classes get loaded first.

To avoid that problem you need to relocate/shade the class names.

But this could also give you problems if jsoup uses its own class names as strings internally, e.g. reflection.

Edited by warjort

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

8 hours ago, warjort said:

Make a new mod for JSoup. This is for example what somebody has done for Rhino

Doesnt it does the same thing?, add the jsoup to the build.gradle but in another recently created mod, why thats a difference?

 

8 hours ago, warjort said:

The classes won't magically appear inside Minecraft at runtime.

What do you mean, i didnt runtime minecraft while adding the library

 

9 hours ago, warjort said:

Use a gradle plugin to include the jsoup classes inside your mod jar

Cause all the problems this could cause me, i prefer not to use it :b

Link to comment
Share on other sites

Quote

Doesnt it does the same thing?, add the jsoup to the build.gradle but in another recently created mod, why thats a difference?

All you have done is make the classes available at compile time.

The jsoup.jar is not a mod so forge won't recognise it.

If you look at that rhino project it has a mod.toml: https://github.com/KubeJS-Mods/Rhino/tree/1.18/main/forge/src/main/resources/META-INF

 

There is at least one other way you can do it: https://forge.gemwire.uk/wiki/Jar-in-Jar

It's not something I have personally used, so I can't tell you what the pros and cons are.

 

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

37 minutes ago, warjort said:

All you have done is make the classes available at compile time.

The jsoup.jar is not a mod so forge won't recognise it.

If you look at that rhino project it has a mod.toml: https://github.com/KubeJS-Mods/Rhino/tree/1.18/main/forge/src/main/resources/META-INF

 

There is at least one other way you can do it: https://forge.gemwire.uk/wiki/Jar-in-Jar

It's not something I have personally used, so I can't tell you what the pros and cons are.

 

so, i create a new mod, add the jsoup library, build/export it, and use it in my main mod to make forge recognize it (also add the mandatory in mods.toml), but how do i use the new mod that has the jsoup library in my main mod, (inside intellij)

Link to comment
Share on other sites

If you are going down that path, you can just repackage the jsoup jar to add a META-INF/mods.toml.

Then you need to publish it somewhere so you can reference it.

 

Since users of your mod will also need to have access to it, probably the easiest place to put it is on curseforge and reference it in your build(s) using: https://www.cursemaven.com/

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

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.