Maven项目生成Shaded Jar仍出现java.lang.NoClassDefFoundError异常
问题描述
开发一款Minecraft Paper服务器插件的辅助工具,采用Maven管理依赖,使用maven-shade-plugin生成可执行的Shaded Jar包。运行Jar包时抛出java.lang.NoClassDefFoundError: org/bukkit/Material异常。
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>CustomItemGenerationTool</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>16</maven.compiler.source> <maven.compiler.target>16</maven.compiler.target> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> <repositories> <repository> <id>papermc-repo</id> <url>https://repo.papermc.io/repository/maven-public/</url> </repository> <repository> <id>sonatype</id> <url>https://oss.sonatype.org/content/groups/public/</url> </repository> </repositories> <dependencies> <dependency> <groupId>io.papermc.paper</groupId> <artifactId>paper-api</artifactId> <version>1.18.2-R0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> </dependencies> </project>
工具代码
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Scanner; public class Main { private static final Scanner scanner = new Scanner(System.in); public static void main(String[] args) { System.out.println("Starting...."); ItemStack item; Material material; int quantity; List<Component> lore; // Material? System.out.print("What material is the item? "); material = Material.getMaterial(scanner.nextLine()); // Quantity? System.out.print("How many are in the stack? (1-64): "); quantity = scanner.nextInt(); item = new ItemStack(material, quantity); // Get item name as component System.out.println("Item Name:"); item.getItemMeta().displayName(getComponent()); // Enchants? Enchantment enchant; int level; System.out.print("Is the item enchanted? "); if (scanner.nextLine().equalsIgnoreCase("y")) { while (!(scanner.nextLine().equalsIgnoreCase("n"))) { System.out.print("What Enchants are on the item? "); enchant = Enchantment.getByKey(new NamespacedKey(NamespacedKey.MINECRAFT, scanner.nextLine())); System.out.print("What level is that enchant? "); level = scanner.nextInt(); item.addUnsafeEnchantment(enchant, level); System.out.println("Another enchant? (y/n)"); } } // Lore as component System.out.print("Does the item have lore? "); if (scanner.nextLine().equalsIgnoreCase("y")) { if (item.lore() == null) { lore = new ArrayList<>(0); } else { lore = item.lore(); } while (!(scanner.nextLine().equalsIgnoreCase("n"))) { lore.add(getComponent()); System.out.println("Another line? (y/n)"); } item.lore(lore); } // ItemFlags? while (!(scanner.nextLine().equalsIgnoreCase("n"))) { System.out.print("Enter flag name: (HIDE_ATTRIBUTES | HIDE_DESTROYS | HIDE_DYE | HIDE_ENCHANTS | HIDE_PLACED_ON | HIDE_POTION_EFFECTS | HIDE_UNBREAKABLE): "); item.addItemFlags(ItemFlag.valueOf(scanner.nextLine())); System.out.println("Another flag? (y/n)"); } // CustomModelData? System.out.print("Does the item have custom model data? (y/n): "); if (scanner.nextLine().equalsIgnoreCase("y")) { item.getItemMeta().setCustomModelData(scanner.nextInt()); } // Unbreakable? System.out.print("Is the item unbreakable? (Y/N) "); if (scanner.nextLine().equalsIgnoreCase("y")) { item.getItemMeta().setUnbreakable(true); } else { item.getItemMeta().setUnbreakable(false); } } private static Component getComponent() { Component component; String name; int[] rgb = new int[3]; HashMap<TextDecoration, TextDecoration.State> decorations = new HashMap<>(); decorations.put(TextDecoration.BOLD, TextDecoration.State.FALSE); decorations.put(TextDecoration.ITALIC, TextDecoration.State.FALSE); decorations.put(TextDecoration.STRIKETHROUGH, TextDecoration.State.FALSE); decorations.put(TextDecoration.OBFUSCATED, TextDecoration.State.FALSE); decorations.put(TextDecoration.UNDERLINED, TextDecoration.State.FALSE); System.out.print("Component Name: "); name = scanner.nextLine(); System.out.println("Component Colour? (y/n):"); if (scanner.nextLine().equalsIgnoreCase("y")) { System.out.print("R (0-255): "); rgb[0] = scanner.nextInt(); System.out.print("G (0-255): "); rgb[1] = scanner.nextInt(); System.out.print("B (0-255): "); rgb[2] = scanner.nextInt(); } System.out.println("Component Decoration? (y/n):"); if (!(scanner.nextLine().equalsIgnoreCase("y"))) { while (scanner.nextLine().equalsIgnoreCase("n")) { System.out.print("Enter decoration name: (BOLD | ITALIC | OBFUSCATED | STRIKETHROUGH | UNDERLINED): "); decorations.put(TextDecoration.valueOf(scanner.nextLine()), TextDecoration.State.TRUE); System.out.println("Another decoration? (y/n)"); } } component = Component.text( name ).color( TextColor.color( rgb[0], rgb[1], rgb[2] ) ).decorations( decorations ); return component; } }
报错堆栈信息
PS C:\Users\gamin\Desktop\natserver\CustomItemGenerationTool> java -jar .\target\CustomItemGenerationTool-1.0-SNAPSHOT-shaded.jar Starting.... What material is the item? STICK Exception in thread "main" java.lang.NoClassDefFoundError: org/bukkit/Material at Main.main(Main.java:27) Caused by: java.lang.ClassNotFoundException: org.bukkit.Material at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 1 more
解决方法
问题核心在于paper-api依赖的scope配置:
providedscope表示该依赖仅在编译阶段可用,运行时由宿主环境(如Paper服务器)提供,因此maven-shade-plugin不会将其打包进最终Jar包。但你的工具是独立运行的Java程序,没有Paper服务器提供这些类,导致运行时找不到org.bukkit.Material。
修改步骤:
- 打开pom.xml,找到
paper-api依赖项,删除<scope>provided</scope>(默认scope为compile),或直接改为<scope>compile</scope>:
<dependency> <groupId>io.papermc.paper</groupId> <artifactId>paper-api</artifactId> <version>1.18.2-R0.1-SNAPSHOT</version> </dependency>
- 重新执行Maven打包命令:
mvn clean package - 运行新生成的shaded Jar包,此时
org.bukkit相关类会被包含在Jar中,异常即可解决。
额外说明:代码中使用的net.kyori.adventure相关类是Paper API的依赖,修改paper-api的scope为compile后,这些依赖会被自动打包进来。
内容的提问来源于stack exchange,提问作者Eyrim
相关产品推荐
相关产品推荐

