使用 Spring Boot 应用程序在运行时编译类

Jor*_*vín 5 java compilation classloader spring-boot

我有两个gradle项目:

  • 一个定义一些业务实体的java项目。
  • 一个依赖于第一个项目的 java Spring Boot API Rest 项目

API Rest 项目公开了一个POST端点,该端点执行一些 Java 代码的运行时编译。

此 Java 代码扩展了一个在业务项目中定义其父级的类。

该代码的编译通过完成InMemoryJavaCompilerhttps://github.com/trung/InMemoryJavaCompiler

根据应用程序的启动方式,会出现两种情况:

  • 启动和调试 API Rest 时IntelliJ工作正常。代码已编译并可以执行。

  • 使用它启动和调试 API Rest 时java -jar不起作用。该 jar 与bootJar任务一起打包。Java 可执行文件来自 JDK

不准确意味着业务项目中定义的InMemoryJavaCompiler类在运行时不被类加载器看到,因此编译失败。

示例堆栈跟踪

2019-01-19 10:33:50.955 ERROR 1636 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mdkt.compiler.CompilationException: Unable to compile the source
[kind=ERROR, line=1, message=package com.foo.entities does not exist]
[kind=ERROR, line=1, message=cannot find symbol
  symbol: class BaseClass]
[kind=ERROR, line=1, message=cannot find symbol
  symbol:   class Entity
  location: class com.foo.myClass]
[kind=ERROR, line=1, message=method does not override or implement a method from a supertype]] with root cause

org.mdkt.compiler.CompilationException: Unable to compile the source
[kind=ERROR, line=1, message=package package com.foo.entities does not exist]
[kind=ERROR, line=1, message=cannot find symbol
  symbol: class BaseClass]
[kind=ERROR, line=1, message=cannot find symbol
  symbol:   class Entity
  location: class com.foo.myClass]
[kind=ERROR, line=1, message=method does not override or implement a method from a supertype]
        at org.mdkt.compiler.InMemoryJavaCompiler.compileAll(InMemoryJavaCompiler.java:106) ~[InMemoryJavaCompiler-1.3.0.jar!/:na]
        at org.mdkt.compiler.InMemoryJavaCompiler.compile(InMemoryJavaCompiler.java:126) ~[InMemoryJavaCompiler-1.3.0.jar!/:na]
Run Code Online (Sandbox Code Playgroud)

Spring Boot 版本是2.1.2,java 是版本 8

我试图编译的代码是这样的,在一行中,但这里的格式是为了提高可读性

package com.foo; 
import com.foo.entities.Entity; 
public class myClass extends BaseClass {
    @Override public void evaluate(Entity entity) { 
        System.out.println(entity); 
    } 
}
Run Code Online (Sandbox Code Playgroud)

当打包和分发为jar??

亲切的问候。