关于Jfinal项目如何使用内置Jetty打成Jar运行

首先说明本分享只适用于maven项目,grandle项目部分插件有所不同。

1.核心引用

<dependency>
    <groupId>com.jfinal</groupId>
    <artifactId>jetty-server</artifactId>
    <version>8.1.8</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.jfinal</groupId>
    <artifactId>jfinal</artifactId>
    <version>3.2</version>
</dependency>

maven插件
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>UTF-8</encoding>
        </configuration>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <skip>true</skip>
        </configuration>
    </plugin>
    <plugin><!--核心打成jar包插件-->
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>lib/</classpathPrefix>
                    <mainClass>top.jkhaled.App</mainClass>
                </manifest>
            </archive>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.10</version>
        <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>
</plugins>

2.把原来在webapp目录的内容全部放在resources目录下

image.png

3.编写启动类

public class App {
    /**
     * 用于在 IDEA 中,通过创建 main 方法的方式启动项目,不支持热加载
     * 本方法存在的意义在于此方法启动的速度比 maven 下的 jetty 插件要快得多
     * <p>
     * 注意:不支持热加载。建议通过 Ctrl + F5 快捷键,来快速重新启动项目,速度并不会比 eclipse 下的热加载慢多少
     * 实际操作中是先通过按 Alt + 5 打开 debug 窗口,才能按 Ctrl + F5 重启项目
     */
    public static void main(String[] args) {
        /**
         * 特别注意:IDEA 之下建议的启动方式,仅比 eclipse 之下少了最后一个参数
         */
        String baseBath = String.valueOf(App.class.getProtectionDomain().getCodeSource().getLocation());
        String classPath, webRootPath, jarPath;
        if (StrKit.notBlank(baseBath) && baseBath.contains("file:/")) {
            // 获取运行操作系统的运行方式  window和linux的细微区别
            boolean windows = System.getProperties().getProperty("os.name").contains("Windows");
            System.out.println(System.getProperties().getProperty("os.name"));
            jarPath = (windows ? "" : "/") + baseBath.substring("file:/".length());
            classPath = (windows ? "" : "/") + jarPath.substring(0, jarPath.lastIndexOf("/")) + "/class-path";
            System.out.println("jarPath:" + jarPath);
            System.out.println("classPath:" + classPath);
            webRootPath = classPath;
            ZipUtil.unzip(jarPath, classPath);
            // 这两步是核心指定 webapp目录和classpath目录
            PathKit.setWebRootPath(webRootPath);
            PathKit.setRootClassPath(classPath);
            // eclipse 启动是4个参数    
            JFinal.start(webRootPath, 1996, "/");
        } else {
            throw new RuntimeException("你丫的路径不对!");
        }
    }
}

5.maven jar 插件中指定这个类为启动类

                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>lib/</classpathPrefix>
                    <mainClass>top.jkhaled.App</mainClass>
                </manifest>

6.执行 mvn install

7.执行 java -jar target/xxxxxx.jar

image.png

启动成功

image.png

访问一个请求成功


备注:

 ZipUtil.unzip(jarPath, classPath);

这个地方用到了 Hutool的解压包,大家可以使用自己解压zip的包。

评论区

正负余

2018-08-27 01:27

大佬请问为什么我这StrKit就直接报NoClassRef呢后面所有引用的jar包都报这个 本地windows运行没问题 但是在windows服务器上就不想

Memorydoc

2018-11-14 16:18

@正负余 我也是这样,请问怎么解决的

npcxu

2018-11-30 12:10

你好 为什么maven install后我生成的还是war包而不是jar包

JFinal

2018-11-30 12:51

@npcxu 下载首页的 dem ,方案全在里头

npcxu

2018-11-30 12:59

@JFinal 好的 谢谢

帅哥天下9

2020-02-18 10:39

@JFinal 波总 这个我在3.2 版本的jfinal 操作成功了 但是在2.2版本的jfinal下未能成功 由于 2.2 中没有这个对外提供的静态方法PathKit.setRootClassPath(classPath); 有方式可以解决吗?

JFinal

2020-02-18 10:41

@帅哥天下9 在你的项目中创建一个 com.jfinal.kit 目录,然后将 4.8 版本的 PathKit.java 复制进去即可

帅哥天下9

2020-02-18 10:46

@JFinal 感谢波总!!!!!

帅哥天下9

2020-02-18 14:07

@JFinal 如果将在自己的项目中 创建com.jfinal.kit 然后将4.8中的PathKit类复制进去以后 打包 执行jar 会有此异常 java.lang.IncompatibleClassChangeError: Expected static method com.jfinal.kit.PathKit.setRootClassPath(Ljava/lang/String;) 经过查询好像是jar包冲突

热门分享

扫码入社