You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3中使用JTE预编译模板抛出ClassNotFoundException问题求助

问题

在Spring Boot 3.2中使用JTE生成非HTML文件,未采用jte-spring-boot-starter-3。本地测试时配置正常,但Docker容器运行应用时抛出ClassNotFoundException。打包后的JAR结构中存在gg.jte.generated.precompiled目录,但调用生成方法时仍报错。

Maven插件配置

<plugin>
    <groupId>gg.jte</groupId>
    <artifactId>jte-maven-plugin</artifactId>
    <version>${jte.version}</version>
    <configuration>
        <sourceDirectory>${project.basedir}/src/main/jte</sourceDirectory>
        <targetDirectory>${project.build.directory}/jte-classes</targetDirectory>
        <contentType>Plain</contentType>
    </configuration>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

TemplateEngine使用代码

@Service
public class GenerateUseCase {
    private final TemplateEngine jteTemplateEngine;

    public GenerateUseCase() throws IOException {
        this.jteTemplateEngine = TemplateEngine.createPrecompiled(ContentType.Plain);
    }

    private void generateFileByTemplate(final Path dir, final Map<String, Object> params,
                                        final String fileName) throws IOException {

        final File file = dir.resolve(fileName).toFile();

        file.createNewFile();

        try (FileOutput output = new FileOutput(file.getAbsoluteFile().toPath(), StandardCharsets.UTF_8)) {
            jteTemplateEngine.render(fileName + ".jte", params, output);
        }
    }
}

报错堆栈

Servlet.service() for servlet [dispatcherServlet] in context with path [/] threw exception [Request processing failed: java.lang.RuntimeException: gg.jte.TemplateNotFoundException: Failed to load ingress.yml.jte] with root cause

java.lang.ClassNotFoundException: gg.jte.generated.precompiled.JteingressymlGenerated
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:593)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
    at gg.jte.runtime.TemplateLoader.load(TemplateLoader.java:25)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
    at gg.jte.TemplateEngine.resolveTemplate(TemplateEngine.java:339)
    at gg.jte.TemplateEngine.render(TemplateEngine.java:228)
    at org.service.GenerateUseCase.generateFileByTemplate(GenerateUseCase.java:151)
解决方案

1. 确保预编译JTE类被打包进JAR

当前JTE插件将生成的类输出到target/jte-classes,但Spring Boot Maven插件默认不会把该目录下的类打包进最终JAR,可通过以下三种方式解决:

方案A:调整JTE插件输出目录到源码目录

修改jte-maven-plugin的targetDirectory为src/main/java(建议将生成的类添加到.gitignore,避免提交):

<configuration>
    <sourceDirectory>${project.basedir}/src/main/jte</sourceDirectory>
    <targetDirectory>${project.basedir}/src/main/java</targetDirectory>
    <contentType>Plain</contentType>
</configuration>

方案B:配置Spring Boot插件包含jte-classes目录

在spring-boot-maven-plugin中添加配置,将jte-classes作为额外类目录:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <additionalClasspathElements>
            <additionalClasspathElement>${project.build.directory}/jte-classes</additionalClasspathElement>
        </additionalClasspathElements>
    </configuration>
</plugin>

方案C:用资源插件复制生成类到classes目录

添加maven-resources-plugin,在构建阶段将jte-classes下的类复制到target/classes:

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-jte-classes</id>
            <phase>process-classes</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/classes</outputDirectory>
                <resources>
                    <resource>
                        <directory>${project.build.directory}/jte-classes</directory>
                        <includes>
                            <include>**/*.class</include>
                        </includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

2. 检查Docker构建流程

确保Dockerfile执行完整的Maven构建,包含generate-sources和package阶段,避免直接复制本地JAR:

FROM maven:3.8.6-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=build /app/target/your-app.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

3. 显式指定类加载器(可选)

若类加载器存在问题,创建TemplateEngine时传入当前类的类加载器:

public GenerateUseCase() throws IOException {
    this.jteTemplateEngine = TemplateEngine.createPrecompiled(ContentType.Plain, getClass().getClassLoader());
}

内容的提问来源于stack exchange,提问作者Alina Didenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:34:52