Spring-boot:run正常但java -jar启动失败,第三方HTTPS服务Bean创建异常
问题分析与解决:JAX-WS服务Bean创建失败(Maven启动正常,Java -jar异常)
问题背景
我们公司的集成Web服务原本用HTTP运行正常,第三方服务强制HTTPS并添加证书后,出现了Bean创建异常:
- 执行
mvn spring-boot:run -Djavax.net.ssl.trustStore=MiJks.jks启动时一切正常 - 但用
java -jar Miapp.jar -Djavax.net.ssl.trustStore=MiJks.jks启动时,无法创建第三方服务的Bean(teleoptiInternalService)
相关配置细节:
- 使用codehaus的
jaxws-maven-plugin生成第三方WSDL代码 - Spring配置中的Bean定义:
<bean id="teleoptiInternalService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"> <property name="serviceInterface" value="com.teleopti.ccc.schemas.sdk._2010._04.TeleoptiCccSdkInternal" /> <property name="wsdlDocumentUrl" value="https://WTWFMWEB01.comunicaciones.tel/TeleoptiWFM/SDK/TeleoptiCccSdkService.svc?wsdl" /> <property name="serviceName" value="TeleoptiCccSdkService" /> <property name="portName" value="TeleoptiOrganizationService1" /> <!-- TODO Endpoint URL should be in a properties file --> <property name="endpointAddress" value="https://WTWFMWEB01.comunicaciones.tel/TeleoptiWFM/SDK/TeleoptiCccSdkService.svc" /> <property name="handlerResolver" ref="wsHandlerResolver" /> <property name="portFeatures"> <bean class="org.apache.cxf.feature.LoggingFeature" /> </property> </bean>
报错信息:
2018-05-28 10:32:55.623 WARN 2172 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teleoptiInternalService' defined in class path resource [applicationContext-teleopti-integration.xml]: Invocation of init method failed; nested exception is javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
问题根源
1. JVM参数传递位置错误
你用java -jar Miapp.jar -Djavax.net.ssl.trustStore=MiJks.jks启动时,把JVM系统属性参数放在了jar包后面,JVM会将-Djavax.net.ssl.trustStore=MiJks.jks当成应用程序的命令行参数,而不是JVM层面的配置参数。这直接导致SSL信任库没有被加载,访问HTTPS的WSDL时出现证书信任问题,最终引发服务Bean创建失败。
2. Maven启动与Java直接启动的核心差异
- Maven启动(
mvn spring-boot:run):Spring Boot的Maven插件会自动处理命令行参数,不管你把-D参数放在哪个位置,插件都会将其转发给JVM进程,所以SSL信任库的配置能被正确读取。 - Java直接启动(
java -jar):JVM的规则是,所有-D开头的系统属性参数必须放在-jar(或者主类名)之前,否则这些参数不会被JVM识别,自然无法生效。
解决办法
把JVM参数移到-jar前面,修改启动命令为:
java -Djavax.net.ssl.trustStore=MiJks.jks -jar Miapp.jar
如果JKS文件不在当前执行目录,需要指定完整路径:
java -Djavax.net.ssl.trustStore=/full/path/to/MiJks.jks -jar Miapp.jar
另外,建议把SSL相关配置统一放到应用配置文件(比如application.properties)中,避免每次启动手动输入参数:
server.ssl.trust-store=classpath:MiJks.jks server.ssl.trust-store-password=your-jks-password
(注意要确保JKS文件被正确打包到classpath中)
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

