一、该问题的重现步骤是什么?
maven 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
2. 打包类型
<packaging>war</packaging>
3. 入口类修改
Application SpringBootServletInitializer{ SpringApplicationBuilder (SpringApplicationBuilder builder) { BladeApplication.(CommonConstant.Application.).sources(Application.)} (String[] args) { BladeApplication.(CommonConstant.Application.args)} }
二、你期待的结果是什么?实际看到的又是什么?
打包成功后的war包,放到tomcat中可以运行。
实际看到
IDEA里可以正常运行,也可以打war包,就是放入tomcat时无法使用
三、你正在使用的是什么产品,什么版本?在什么操作系统上?
spring-boot版本 win10系统 idea jdk8 tomcat8.5
四、请提供详细的错误堆栈信息,这很重要。
021-11-17 17:49:59.927 WARN 8652 --- [ost-startStop-1] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
2021-11-17 17:49:59.936 INFO 8652 --- [ost-startStop-1] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-11-17 17:49:59.977 ERROR 8652 --- [ost-startStop-1] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:177)
The following method did not exist:
org.apache.tomcat.util.modeler.Registry.disableRegistry()V
The method's class, org.apache.tomcat.util.modeler.Registry, is available from the following locations:
jar:file:/D:/devsoft/java/tomcat/apache-tomcat-8.5.72/lib/tomcat-coyote.jar!/org/apache/tomcat/util/modeler/Registry.class
The class hierarchy was loaded from the following locations:
org.apache.tomcat.util.modeler.Registry: file:/D:/devsoft/java/tomcat/apache-tomcat-8.5.72/lib/tomcat-coyote.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.apache.tomcat.util.modeler.Registry
17-Nov-2021 17:49:59.978 涓ラ噸 [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: 鏃犳硶鍚姩缁勪欢[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/blade-api]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:727)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1016)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1903)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:173)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:153)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:95)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
... 10 more
Caused by: java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:177)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:158)
... 22 more
17-Nov-2021 17:49:59.980 涓ラ噸 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR 閮ㄧ讲 Web 搴旂敤绋嬪簭 archive [D:\devsoft\java\tomcat\apache-tomcat-8.5.72\webapps\blade-api.war] 鏃跺嚭閿?
java.lang.IllegalStateException: 鍚姩瀛愮骇鏃跺嚭閿?
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:757)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:727)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1016)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1903)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.catalina.LifecycleException: 鏃犳硶鍚姩缁勪欢[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/blade-api]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
... 9 more
Caused by: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:173)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:153)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:95)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
... 10 more
Caused by: java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:177)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:158)
... 22 more
五、若有更多详细信息,请在下面提供。
希望作者能能重视下这个问题实践下。论坛上的几个方法都试了。在群里也没有回复。
按照如下步骤尝试,如果还不行,麻烦发一个邮件到bladejava@qq.com附上帖子地址并说明使用的bladex版本
1. 添加tomcat依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
2. blade-core-boot排除undertow依赖
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-boot</artifactId>
<exclusions>
<exclusion>
<groupId>org.springblade</groupId>
<artifactId>blade-core-cloud</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</exclusion>
</exclusions>
</dependency>
3.pom文件修改打包类型为war
<groupId>org.springblade</groupId>
<artifactId>BladeX-Boot</artifactId>
<packaging>war</packaging>
<version>2.8.2.RELEASE</version>
4.添加war包插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!--如果想在没有web.xml文件的情况下构建WAR,请设置为false。-->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
5.application.yaml添加修改
#服务器配置
server:
port: 80
spring:
application:
name: blade-api
profiles:
active: dev
main:
allow-bean-definition-overriding: true
6.Application类修改,最重要的一步(blade 4.x以上版本)
@EnableScheduling
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
BladeApplication.run(CommonConstant.APPLICATION_NAME, Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return BladeApplication.createSpringApplicationBuilder(CommonConstant.APPLICATION_NAME, Application.class, application).sources(Application.class);
}
}
7.打包
mvn package -Dmaven.test.skip=true
======补充说明=====
8. 如果是blade 4.x以前的版本,需要新建一个启动类 BladeXApplication,原版代码如下:https://gitee.com/smallc/blade-tool/blob/master/blade-core-launch/src/main/java/org/springblade/core/launch/BladeApplication.java
比如创建一个BladeXApplication到业务工程,然后拷贝如下代码,之后把启动类的BladeApplication改成BladeXApplication即可:
package org.springblade.core.launch;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.launch.constant.NacosConstant;
import org.springblade.core.launch.service.LauncherService;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.*;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 项目启动器,搞定环境变量问题
*
* @author Chill
*/
public class BladeXApplication {
/**
* Create an application context
* java -jar app.jar --spring.profiles.active=prod --server.port=2333
*
* @param appName application name
* @param source The sources
* @return an application context created from the current state
*/
public static ConfigurableApplicationContext run(String appName, Class source, String... args) {
SpringApplicationBuilder builder = createSpringApplicationBuilder(appName, source, args);
return builder.run(args);
}
public static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class source, String... args) {
return createSpringApplicationBuilder(appName, source, null, args);
}
public static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class source, SpringApplicationBuilder builder, String... args) {
Assert.hasText(appName, "[appName]服务名不能为空");
// 读取环境变量,使用spring boot的规则
ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addFirst(new SimpleCommandLinePropertySource(args));
propertySources.addLast(new MapPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, environment.getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, environment.getSystemEnvironment()));
// 获取配置的环境变量
String[] activeProfiles = environment.getActiveProfiles();
// 判断环境:dev、test、prod
List<String> profiles = Arrays.asList(activeProfiles);
// 预设的环境
List<String> presetProfiles = new ArrayList<>(Arrays.asList(AppConstant.DEV_CODE, AppConstant.TEST_CODE, AppConstant.PROD_CODE));
// 交集
presetProfiles.retainAll(profiles);
// 当前使用
List<String> activeProfileList = new ArrayList<>(profiles);
Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString;
if(builder == null){
// 如果builder为空 创建 此操作将启动内嵌web容器 以jar模式启动
builder = new SpringApplicationBuilder(source);
}
String profile;
if (activeProfileList.isEmpty()) {
// 默认dev开发
profile = AppConstant.DEV_CODE;
activeProfileList.add(profile);
builder.profiles(profile);
} else if (activeProfileList.size() == 1) {
profile = activeProfileList.get(0);
} else {
// 同时存在dev、test、prod环境时
throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]");
}
String startJarPath = BladeApplication.class.getResource("/").getPath().split("!")[0];
String activePros = joinFun.apply(activeProfileList.toArray());
System.out.printf("----启动中,读取到的环境变量:[%s],jar地址:[%s]----%n", activePros, startJarPath);
Properties props = System.getProperties();
props.setProperty("spring.application.name", appName);
props.setProperty("spring.profiles.active", profile);
props.setProperty("info.version", AppConstant.APPLICATION_VERSION);
props.setProperty("info.desc", appName);
props.setProperty("file.encoding", StandardCharsets.UTF_8.name());
props.setProperty("blade.env", profile);
props.setProperty("blade.name", appName);
props.setProperty("blade.is-local", String.valueOf(isLocalDev()));
props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true");
props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION);
props.setProperty("loadbalancer.client.name", appName);
Properties defaultProperties = new Properties();
defaultProperties.setProperty("nacos.logging.default.config.enabled", "false");
defaultProperties.setProperty("spring.main.allow-bean-definition-overriding", "true");
defaultProperties.setProperty("spring.sleuth.sampler.percentage", "1.0");
defaultProperties.setProperty("spring.cloud.alibaba.seata.tx-service-group", appName.concat(NacosConstant.NACOS_GROUP_SUFFIX));
defaultProperties.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[0].data-id", NacosConstant.sharedDataId());
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[0].group", NacosConstant.NACOS_CONFIG_GROUP);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[0].refresh", NacosConstant.NACOS_CONFIG_REFRESH);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[1].data-id", NacosConstant.sharedDataId(profile));
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[1].group", NacosConstant.NACOS_CONFIG_GROUP);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[1].refresh", NacosConstant.NACOS_CONFIG_REFRESH);
builder.properties(defaultProperties);
// 加载自定义组件
List<LauncherService> launcherList = new ArrayList<>();
ServiceLoader.load(LauncherService.class).forEach(launcherList::add);
launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).collect(Collectors.toList())
.forEach(launcherService -> launcherService.launcher(builder, appName, profile, isLocalDev()));
return builder;
}
/**
* 判断是否为本地开发环境
*
* @return boolean
*/
public static boolean isLocalDev() {
String osName = System.getProperty("os.name");
return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equalsIgnoreCase(osName));
}
}
@EnableScheduling
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
BladeXApplication.run(CommonConstant.APPLICATION_NAME, Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return BladeXApplication.createSpringApplicationBuilder(CommonConstant.APPLICATION_NAME,Application.class,application).sources(Application.class);
}
}
可以了,非常感谢
按照上面的配置结果,tomcat启动获取nacos数据源配置信息时,获取不到值,你们有这个问题吗
扫一扫访问 Blade技术社区 移动端