主题:beet工程,使用外部lib 的SpringBoot jar包运行问题

hkl5449951 2019年06月11日 31

问题背景:springboot工程中最大的部分一般是lib文件夹,所以某些情况需要lib放外部,这样如果不改动依赖,每次改动class下的东西,也不需要上传太多东西

使用maven依赖构建beetl的springboot工程

主类:

package com.example.beetl;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class BeetlApplication {

    public static void main(String[] args) {
        SpringApplication.run(BeetlApplication.class, args);    }

}

测试

package com.example.beetl;
import java.util.Calendar;
public class StringUtilExtBeetl {
    public Long getTime(){
        Calendar calendar = Calendar.getInstance();        calendar.set(Calendar.DAY_OF_MONTH,1);        calendar.add(Calendar.MONTH, 1);        calendar.set(Calendar.HOUR_OF_DAY, 0);        calendar.set(Calendar.MINUTE,0);        calendar.set(Calendar.SECOND, 0);        calendar.set(Calendar.MILLISECOND, 0);        return calendar.getTimeInMillis();    }

    public  String intToMask(int bitMask) {
        if(bitMask > 32)
            return null;        int[] tmpMask = {0, 0, 0, 0};        int times = bitMask / 8;        int i = 0;        for(; i < times ; i++)
        {
        tmpMask[i] = 255;        }

        for(int j = 1; j <= 8; j++) {
            if(j <= bitMask - times*8)
                tmpMask[i] = 2*tmpMask[i] + 1;            else                tmpMask[i] = 2*tmpMask[i];        }
        return tmpMask[0] + "." + Integer.toString(tmpMask[1]) + "." +Integer.toString(tmpMask[2]) + "." + Integer.toString(tmpMask[3]);    }

}

测试入口:

package com.example.beetl;import org.beetl.core.Configuration;import org.beetl.core.GroupTemplate;import org.beetl.core.ResourceLoader;import org.beetl.core.Template;import org.beetl.core.resource.StringTemplateResourceLoader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.io.IOException;@RestController@RequestMapping("beetl")
public class TestController {

    GroupTemplate groupTemplate;    ResourceLoader resourceLoader;    Configuration cfg;    private GroupTemplate getGroupTemplate(){
        if(groupTemplate!=null){
            return groupTemplate;        }else{
            resourceLoader = new StringTemplateResourceLoader();            try {
                cfg = Configuration.defaultConfiguration();            } catch (IOException e) {
                e.printStackTrace();            }
            groupTemplate = new GroupTemplate(resourceLoader, cfg);            return groupTemplate;        }

    }
    @RequestMapping("test1")
    public void test1(){
        String template = "${strutil2.getTime()}";        Template st = getGroupTemplate().getTemplate(template);        System.out.println(st.render());    }
}

pom文件:

<?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>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.21.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <groupId>com.example</groupId>    <artifactId>beetl</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>beetl</name>    <description>Demo project for Spring Boot</description>    <properties>        <java.version>1.8</java.version>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>com.ibeetl</groupId>            <artifactId>beetl</artifactId>            <version>2.7.23</version>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-jar-plugin</artifactId>                <configuration>                    <!--不打包资源文件-->                    <excludes>                        <exclude>*.**</exclude>                        <exclude>static/**</exclude>                        <exclude>templates/**</exclude>                        <exclude>cfg/**</exclude>                    </excludes>                    <archive>                        <manifest>                            <addClasspath>true</addClasspath>                            <!--MANIFEST.MF 中 Class-Path 加入前缀-->                            <classpathPrefix>lib/</classpathPrefix>                            <!--jar包不包含唯一版本标识-->                            <useUniqueVersions>false</useUniqueVersions>                            <!--指定入口类-->                            <mainClass>com.example.beetl.BeetlApplication</mainClass>                        </manifest>                        <manifestEntries>                            <!--MANIFEST.MF 中 Class-Path 加入资源文件目录-->                            <!--本地依赖包需要手动 加入Class-Path ,否则无法找到-->                            <Class-Path>./config/</Class-Path>                        </manifestEntries>                    </archive>                    <outputDirectory>${project.build.directory}</outputDirectory>                </configuration>            </plugin>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-dependency-plugin</artifactId>                <executions>                    <execution>                        <id>copy-dependencies</id>                        <phase>package</phase>                        <goals>                            <goal>copy-dependencies</goal>                        </goals>                        <configuration>                            <outputDirectory>                                ${project.build.directory}/lib/
                            </outputDirectory>                        </configuration>                    </execution>                </executions>            </plugin>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>                <configuration>                    <!--重写包含依赖,包含不存在的依赖,jar里没有pom里的依赖-->                    <includes>                        <include>                            <groupId>null</groupId>                            <artifactId>null</artifactId>                        </include>                    </includes>                    <layout>ZIP</layout>                    <!--使用外部配置文件,jar包里没有资源文件-->                    <addResources>true</addResources>                    <outputDirectory>${project.build.directory}</outputDirectory>                </configuration>                <executions>                    <execution>                        <goals>                            <goal>repackage</goal>                        </goals>                        <configuration>                            <!--配置jar包特殊标识 配置后,保留原文件,生成新文件 *-run.jar -->                            <!--配置jar包特殊标识 不配置,原文件命名为 *.jar.original,生成新文件 *.jar -->                            <!--<classifier>run</classifier>-->                        </configuration>                    </execution>                </executions>            </plugin>        </plugins>    </build></project>

beetl.properties:

FNP.strutil2 = com.example.beetl.StringUtilExtBeetl

其他springboot默认配置

最终构建后项目结构(可能config下需要手动自己加入配置文件):

image.png

启动脚本:

java -Xbootclasspath/a:E:\IdeaProjects\allen\beetl\target\lib -jar beetl-0.0.1-SNAPSHOT.jar

启动后访问:

http://localhost:8080/beetl/test1

服务器报错找不到类,怀疑是ObjectUtil的ClassLoader(APPclassloader)没有工程jar内的那些classes

2019-06-11 15:56:53.304 ERROR 12816 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: 鍒濆鍖栧け璐 with root causejava.lang.ClassNotFoundException: com.example.beetl.StringUtilExtBeetl        at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_161-1-redhat]        at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_161-1-redhat]        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) ~[na:1.8.0_161-1-redhat]        at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_161-1-redhat]        at java.lang.Class.forName0(Native Method) ~[na:1.8.0_161-1-redhat]        at java.lang.Class.forName(Class.java:264) ~[na:1.8.0_161-1-redhat]        at org.beetl.core.om.ObjectUtil.getClassByName(ObjectUtil.java:600) ~[beetl-2.7.23.jar:na]        at org.beetl.core.GroupTemplate.initFunction(GroupTemplate.java:200) ~[beetl-2.7.23.jar:na]        at org.beetl.core.GroupTemplate.init(GroupTemplate.java:165) ~[beetl-2.7.23.jar:na]        at org.beetl.core.GroupTemplate.<init>(GroupTemplate.java:141) ~[beetl-2.7.23.jar:na]        at com.example.beetl.TestController.getGroupTemplate(TestController.java:30) ~[classes!/:0.0.1-SNAPSHOT]        at com.example.beetl.TestController.test1(TestController.java:38) ~[classes!/:0.0.1-SNAPSHOT]        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161-1-redhat]        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161-1-redhat]        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161-1-redhat]        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161-1-redhat]        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:854) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:765) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.24.RELEASE.jar:4.3.24.RELEASE]        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.40.jar:8.5.40]        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.40.jar:8.5.40]        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_161-1-redhat]        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_161-1-redhat]        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.40.jar:8.5.40]        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161-1-redhat]

image.png

闲大赋 2019年06月11日

用2.9.10吧,这个bug已经修复过了,你这个版本较老

错误原因是老版本的classloader么有考虑到springboot提供的,现在以他的为准