idea 部署SpringBoot项目时打成jar包一些坑的总结

时间:2023-01-02 09:37:57

前一段时间,公司分配给我做一些微服务的功能,比如一些分析、一些可以拿出来的模块,所以采用了SpringBoot搭建的微服务项目,至于关于SpringBoot的介绍,这里就不展开了。今天主要写的是这两天我需要把我本地的项目部署到服务器上,遇到的一个问题。还有我这两天查看网上的一些关于SpringBoot部署发现的其他人发现的一些问题,在这里总结一下,用于以后能够自己能够快速查看解决,当然如果能够帮助大家就更好了。

SpringBoot部署到服务器,首先我们需要将项目打成jar包,然后上传到服务器上,在执行jar。

spring-boot-maven-plugin

SpringBoot打成jar包我们一般使用spring-boot-maven-plugin这个插件,当配置了该插件后,运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“java -jar”命令就可以直接运行。这在很大程度上简化了应用的部署,只需要安装了 JRE 就可以运行。该插件现在最新的版本应该是1.5.9.RELEASE,不过因为我的项目是使用了下面这个配置:
idea 部署SpringBoot项目时打成jar包一些坑的总结
所以 我本地的spring-boot-maven-plugin的版本是1.5.9.RELEASE的版本的,当然两者的区别我就没有仔细的研究了。

当然该插件在使用的时候有一个属性需要知道一下start-class,因为SpringBoot项目的启动类是一个main方法,所以我们在使用插件打包的时候需要注意一下,如果不注意可能会报错,下面会写。为什么说需要注意start-class这个属性呢,是因为spring-boot-maven-plugin在打成jar包时会默认找public static void main(String[] args){*}方法,这时候如果你的项目有多个main方法,这时候就会有问题了,所以你可以删掉其他的main方法,只留SprngBoot的入口main方法,或者在pom.xml中用上述属性指定你的项目指定方法,比如:
idea 部署SpringBoot项目时打成jar包一些坑的总结
上面的就是我指定的BinggouLogAnalysisApplication这个里面的启动类。当然我建议无论你是否有多个main方法,都指定一下,防止以后多一个main方法,到时候报错,不知道为啥。

SpingBoot项目Tomcat常用配置

SpringBoot集成的web容器有我们常用的tomcat容器或者Jetty容器,具体的由配置决定,当然其默认集成的是tomcat容器,
这也说明了,只要我们打成jar包,理论上该jar在任何一个有JRE的服务器上即可运行.,不需要再在服务器上配置tomcat等web容器,这也体现了SpringBoot的微服务的概念。下面是一些tomcat的常用配置:

# tomcat最大线程数,默认为200
server.tomcat.max-threads=800
# tomcat的URI编码
server.tomcat.uri-encoding=UTF-8
# 存放Tomcat的日志、Dump等文件的临时文件夹,默认为系统的tmp文件夹(如:C:\Users\Shanhy\AppData\Local\Temp)
server.tomcat.basedir=H:/springboot-tomcat-tmp
# 打开Tomcat的Access日志,并可以设置日志格式的方法:
#server.tomcat.access-log-enabled=true
#server.tomcat.access-log-pattern=
# accesslog目录,默认在basedir/logs
#server.tomcat.accesslog.directory=
# 日志文件目录
logging.path=H:/springboot-tomcat-tmp
# 日志文件名称,默认为spring.log
logging.file=myapp.log

打jar包的问题

SpringBoot将项目打成jar包,在网上有两种形式一种是使用idea工具打成jar包这有一个我觉得挺详细的说明的在IDEA中如何将Spring boot项目打包成可执行的jar包并发布到linux服务器,还有一种是直接在cmd中切换到项目所在目录,然后执行mvn package 或者添加一个clean :mvn clean package。当然这种方法你可以使用windows系统的默认的cmd.exe程序,还可以用idea或者eclipse,调用cmd的功能。

1.说一下我自己的项目遇到的一个问题,就是我在打jar包的时候,打包失败,报了一个这个错误:

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.986 s
[INFO] Finished at: 2018-01-26T10:01:04+08:00
[INFO] Final Memory: 34M/278M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.7.RELEASE:repackage (default) on project ***: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.7.RELEASE:
repackage failed: Plugin org.springframework.boot:spring-boot-maven-plugin:1.5.7.RELEASE or one of its dependencies could not be resolved: Could not find artifact org.codehaus.plexus:plexus-interpolation:jar:1.21 in Public Reposi
tories (http://****/nexus/content/groups/public/) -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException

当然上面的错误是我解决之后,为了演示重现的。
从上面的报错信息中我们可以看到:报的是不能执行目标插件spring-boot-maven-plugin:1.5.7.RELEASE,是因为少了spring-boot-maven-plugin:1.5.7.RELEASE插件或者少了jar包org.codehaus.plexus:plexus-interpolation:jar:1.21,
当时的报错信息不止少了这一个,是少了很多,我当时看到少jar包,我的第一反应是看我的pom.xml对于这些jar的引用,但是没找到,最后仔细研究了一下报错信息发现了这一句:one of its dependencies could not be resolved,它的依赖jar包。这也说明了这个是spring-boot-maven-plugin插件的依赖,是在插件的自己的引用,我们这边没法改这些依赖jar的版本。
我查了我本地的jar,发现这些jar包的低版本都有,但是没有报错的版本,我又看了我们公司的私服,也没有,所以我就想着把spring-boot-maven-plugin插件的版本降低一些,但是没用,它的所有版本的依赖的jar版本都是一样的。。这样只能自己从网上找相应的jar然后存在本地的仓库,并且上传到公司的私服上去了。bug解决

这里说一个小常识,就是对于他们提示的org.springframework.boot:spring-boot-maven-plugin:1.5.7.RELEASE这样的错误,我们在查询我们仓库的时候怎么定位到它的路径呢,其实很简单它的路径就是org/springframework/boot/spring-boot-maven-plugin,我想不要我再说什么了。并且我们可以根据上面的提示直接写出它在pom.xml的jar包引用:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>1.5.7.RELEASE</version>
        </dependency>

以“:”分割,第一部分是groupId,第二部分是artifactId,第三部分就是版本version了。

2.我在网上查看资料的时候,发现了有一个bug很多,但是我不明报为什么又这么多人会有这个bug,感觉很不可思议的,我感觉只要对SpringBoot有一点研究的,应该都不会出现的:

Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.0.RELEASE:repackage (default) on project springBootDemo: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.4.0.RELEASE:repackage failed: Unable to find main class -> [Help 1] 

就是这个错,其主要信息是“Unable to find main class”,也就是没有找到main方法,其实我觉的对于SpringBoot项目,它的main方法应该是最重要的把,在它的类上应该需要配置很多的注解的,要不项目也没法启动的,demo流程也没法走通的。
其实上面的错就是上了main方法,或者main方法的类上面少了@SpringBootApplication注解。因为spring-boot-maven-plugin插件必须注解@SpringBootApplication重写main方法。

下面赋一下我的SpringBoot的main方法:

@SpringBootApplication
@RestController
@ServletComponentScan("***.***.***")
@ComponentScan(basePackages={"***.***.***"})
@MapperScan(basePackages={"***.***.***"})//Mapper扫描注解
@EnableScheduling //定时任务注解
public class ***{

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

我在这说一下上面的一些注解:
@SpringBootApplication
这个注解是SpringBoot的一个组合注解,用于组合以前的Spring项目的 @Configuration,@EnableAutoConfiguration,@ComponentScan。
这三个注解也就是说
@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

@Configuration的注解类标识这个类可以使用Spring IoC容器作为bean定义的来源。@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册为在Spring应用程序上下文中的bean。@EnableAutoConfiguration:能够自动配置spring的上下文,试图猜测和配置你想要的bean类,通常会自动根据你的类路径和你的bean定义自动配置。
@ComponentScan:会自动扫描指定包下的全部标有@Component的类,并注册成bean,当然包括@Component下的子注解@Service,@Repository,@Controller。

@RestController
这个注解也是SpringBoot的一个组合注解,它相当于@ResponseBody + @Controller。至于这两个注解的功能就不细说了。

@ServletComponentScan
该注解主要用于当使用Spring boot的嵌入式servlet容器时,可以通过Spring bean或扫描Servlet组件的方式注册Servlet、Filter和Servlet规范的所有监听器,后面的路径就是扫描的路径,他会扫描改路径下的包以及所有子包。这里就要说一下SpringBoot的一个很蛋疼的事情了,我们都知道SpringBoot的Application启动类,是非常重要的,这时候我们想要写一个servlet接口,需要用到service和dao以及mapper,但是可能你会发现你写的@service,@mapper注解,扫描不到,这是因为SpringBoot默认的扫描路径是你的Application入口类的子包以及它下面的包,如果你的代码不在这个范围,那么SpringBoot是扫描不到的。

@ComponentScan、@MapperScan

这两个和上面的类似,都是指定扫描的路径的,这个路径你可以配置多个比如:

basePackages={"***.***.***","***.***.***"}

@EnableScheduling

这个注解使用于SpringBoot的定时任务的注解,加上这个注解,SpringBoot就会扫描 有@Scheduled(cron=”0 0 10 * * ?”)的类作为定时任务。详细的大家可以查看下其他的资料。

上面是我发现的几个问题,如果以后还有其他的问题,我会一一添加的。

当然对于SpringBoot的部署是很简单的,只需要把项目打成的jar上传的服务器上切换到相应的目录,然后执行

java -jar ***.jar 

就可以了

生成jar包名称没有带版本号

在服务器上生成jar时,生成没问题,同事发现生成的jar包名没有带项目的版本号,但是我的pom文件的上面的确指定了版本

    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <groupId>bg_anaytics</groupId>
    <artifactId>bg_anaytics</artifactId>
    <version>1.0.0-SNAPSHOT</version>

后来搜了一下,发现了这样一个问题,就是我的build里面加了finalName这个属性是指定生成的jar包名称的。屏蔽它就可以了,当然你想指定jar名称的话,需要配置一下这个finalName。

    <build>
        <finalName>bg_anaytics</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <!--在添加了该插件之后,当运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“java -jar”命令就可以直接运行。这在很大程度上简化了应用的部署,只需要安装了 JRE 就可以运行。-->
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

从网上偶尔看到了一个可能有用的build属性
idea 部署SpringBoot项目时打成jar包一些坑的总结