FEL,项目实装记录

Posted on 2019-09-06 15:37  用户注册了一次  阅读(307)  评论(4编辑  收藏  举报

FEL,即Fast EL ,版本0.8,具体内容我就不贴了,自行百度

实装遇到的问题:

Spring Boot 打包后无法进行表达式编译.

 

根据百度以及源码,确定这东西是在用JavaCompiler将表达式编译成java代码.

打包后报错的内容是类找不到.

首先确定了compiler找到了(自行打断点)

 

然后问题定位到了Spring Boot特殊的打包机制下没办法使用默认的ClassLoader和FileManager

故覆盖FEL的FelCompiler16类,

将classLoader替换成 ApplicationContextHelper.getContext().getClassLoader()

将standardFileManager替换成 自制 FileManager

 

自制 FileManager修改:

参考 http://atamur.blogspot.com/2009/10/using-built-in-javacompiler-with-custom.html (需爬梯子)

在该文提供的源码基础上注意修改两部分

1.Manager中返回UnSupportedOpreation的方法全部代理standardFileManager方法(共6个)

2.Finder中processJar方法修改javaUri的取值逻辑如下,以支持多层jar包

 1     private List<JavaFileObject> processJar(URL packageFolderURL) {
 2         List<JavaFileObject> result = new ArrayList<JavaFileObject>();
 3         try {
 4             StringBuilder jarUri= new StringBuilder();
 5             String[] splited = packageFolderURL.toExternalForm().split("!");
 6             // 这里更改了源代码,支持多层jar包 !访问
 7             for (int i = 0; i < splited.length-1; i++) {
 8                 jarUri.append(splited[i]);
 9                 if(splited[i+1].contains(".jar")){
10                     jarUri.append("!");;
11                 }else {
12                     jarUri.append("!/");
13                 }
14             }
15             JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection();
16             String rootEntryName = jarConn.getEntryName();
17             int rootEnd = rootEntryName.length()+1;
18 
19             Enumeration<JarEntry> entryEnum = jarConn.getJarFile().entries();
20             while (entryEnum.hasMoreElements()) {
21                 JarEntry jarEntry = entryEnum.nextElement();
22                 String name = jarEntry.getName();
23                 if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE_EXTENSION)) {
24                     URI uri = URI.create(jarUri  + name);
25                     String binaryName = name.replaceAll("/", ".");
26                     binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", "");
27 
28                     result.add(new CustomizeJavaFileObject(binaryName, uri));
29                 }
30             }
31         } catch (Exception e) {
32             throw new RuntimeException("Wasn't able to open " + packageFolderURL + " as a jar file", e);
33         }
34         return result;
35     }

有空再把完整的源码贴出来吧,

这个问题基本搜不到,希望帮助有缘人.