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 }
有空再把完整的源码贴出来吧,
这个问题基本搜不到,希望帮助有缘人.
来源:博客园
作者:用户注册了一次
链接:https://www.cnblogs.com/user-for-once/p/11475147.html