升级相关问题

本文汇总了 SOFABoot 版本升级中出现的常见问题及其解决方案。

升级前有哪些环节准备

在升级前,必须安装 JDK 7 和 Maven 3.2.5。具体安装步骤,可参考文档 配置 SOFABoot 环境

如何激活不同环境配置

当您需要在不同环境下(如开发环境、测试环境、预发布环境、生产环境)提供不同的配置时,可以在启动 SOFABoot 应用时加上以下 JVM 启动参数:

-Dspring.profiles.active=${workspace_name}

更多信息,请参见 技术栈使用指南

完成编译后,如何在本地运行

在工程根目录下执行下列命令:

  1. mvn clean install

  2. java -jar ./target/${file.name}-executable.jar (使用 java -jar 命令运行一个 Fat Jar,在 SOFAStack 上部署应用也是这种方式)

当然本地开发时,可以直接使用 main 函数启动整个应用。

更多信息,参见 本地编译运行

如何使用占位符

可以通过配置文件统一管控所有的普通 bean 的配置。

以 SOFARPC 中间件为例,支持对 test-url 进行占位符配置,如下所示:

<sofa:reference id="sampleRpcService"
interface="com.alipay.sofaboot.serverone.facade.rpc.SampleRpcService">
    <sofa:binding.tr>
        <sofa:global-attrstest-url="${test.url}"/>
    </sofa:binding.tr>
</sofa:reference>

如何访问默认关闭的敏感端点(Sensitive Endpoints)

SOFABoot 2.5.0 及以上版本解决了因 Endpoints 信息暴露过多而导致的安全问题,默认关闭一些具备安全风险的 Endpoints。如果您需要开启相应的 Endpoints,请参考 Spring Boot 使用文档

SOFABoot 是否支持分布式 Session

SOFABoot 不支持分布式 Session。

采用 SOFABoot 框架后,建议由用户在 Spring Boot 基础上自主进行 Session 的管理和维护。存储方案可继续使用 OCS。

分布式 session 的中间件在 SOFABoot 3.x 中的版本要求

alipay-session 在 SOFABoot 中已经不支持了,需要使用 Spring Session 进行替换。

<dependency>
    <groupId>com.alipay.session</groupId>
    <artifactId>alipay-session-ocs</artifactId>
    <version>1.0.3</version>
</dependency>
<dependency>
    <groupId>com.alipay.session</groupId>
    <artifactId>alipay-session-core</artifactId>
    <version>1.0.3</version>
</dependency>

日志中出现 StackOverFlow 错误

现象

您可能在日志中看到以下堆栈错误:

Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError:
Exceptionin thread java.lang.StackOverflowError
  at java.util.Hashtable.containsKey(Hashtable.java:306)
  at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:36)
  at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
  at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
  at org.apache.log4j.Category.<init>(Category.java:53)
  at org.apache.log4j.Logger..<init>(Logger.java:35)
  at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
  at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
  at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
  at org.apache.log4j.Category..<init>(Category.java:53)
  at org.apache.log4j.Logger..<init>(Logger.java:35)
  at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
  at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
  subsequent lines omitted...

原因

这是由于 org.slf4j:log4j-over-slf4jlog4j:log4j 存在冲突而导致的。

解决方案

在 ClassPath 中删除 log4j-over-slf4j 依赖即可解决该问题。

如何引入 Spring Boot 的 Web 容器

  • 引入 spring-boot-starter-web,默认依赖并启动的 Web 容器是 Tomcat,依赖信息类似如下:

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  • 如果要引入 Jetty 作为 Web 容器,可以参考 Spring Boot 官方文档 进行配置。

在 SOFABoot 工程中如何处理自定义 filter

SOFABoot 工程中没有 Spring 工程的 web.xml,如果原 Spring MVC 的 web.xml 配置文件有自定义配置 filter,可以参考 Spring Boot 官方迁移 Servlets、Filters、listeners 的方法,也可以参考其它 Spring Boot 对应的 Servlet、Filter、Listener 配置教程。

日志中出现 ConverterRegistry.addConverter 报错

现象

在日志中出现如下记录:

Causedby:java.lang.NoSuchMethodError:org.springframework.core.convert.converter.ConverterRegistry.addConverter(Ljava/lang/Class;Ljava/lang/Class;Lorg/springframework/core/convert/converter/Converter;)

原因

这是由于 Spring 版本冲突所导致。

解决方案

目前的 Spring 统一版本为 4.3.4.RELEASE,删除间接引入的其他版本即可解决该问题。

日志中出现 LoggerSpaceManager.getLoggerBySpace 报错

现象

在日志中出现如下记录:

Causedby:java.lang.NoSuchMethodError: com.alipay.sofa.common.log.LoggerSpaceManager.getLoggerBySpace(Ljava/lang/String;Lcom/alipay/sofa/common/log/SpaceId;Ljava/util/Map;)Lorg/slf4j/Logger;

原因

从 2.2.X 版本后,由于 ArtifactId sofa-middleware-log 升级为 sofa-common-tools,所以当使用 SOFABoot 2.2.X 的版本时,保证 classpath 依赖的是 sofa-common-tools(版本已经管控不需要用户显示添加版本) 同时排除掉 sofa-middleware-log 依赖即可以解决冲突问题。

解决方案

删除以下间接依赖:

<dependency>
      <groupId>com.alipay.sofa.common.log</groupId>
      <artifactId>sofa-middleware-log</artifactId>
</dependency>

并引入以下依赖:

<dependency>
     <groupId>com.alipay.sofa.common</groupId>
     <artifactId>sofa-common-tools</artifactId>
</dependency>

SOFALite 应用升级到 SOFABoot 3.2.2 之后,应用无法启动

现象

出现如下报错:

Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException:Couldnot resolve placeholder 'spring.application.name'in value "${spring.application.name}"

原因

工程中 profile 配置出现问题。

解决方案

调整 main 函数所在模块中 pom.xml 文件中的 Build 里面的关于 Profile 的配置。可参见 技术栈使用指南 以及标准 Demo 的 Build 内容进行调整。

将 RPC 服务提供者和消费者工程从 SOFABoot 2.2.5 升级到 3.2.2 后,调用 RPC 服务报错

现象

出现如下报错:

com.alipay.remoting.exception.DeserializationException:Server deserialize request exception!

原因

Hessian 包冲突。

解决方案

把服务端和客户端的 maven tree 打印出来,然后和标准 demo 的 maven tree 对比一下。其中,重点关注 netty、protobuf、typesafe 与 hessian 的版本。如果版本不一致,建议升级对应版本。

SOFAMVC 在 SOFABoot 3.x 中不支持,如何实现迁移升级

解决方案

支持以下两个方案:

  • 使用 Spring MVC + security 包的方案(推荐)。

  • 临时将 SOFABoot 升级到 3.3.1 来支持 SOFAMVC,但可能会出现兼容性问题。

SOFABoot 2.2.5 升级到 SOFABoot 3.2.1 后出现 Invalid bean definition with name dataSource 报错

现象

出现如下报错:

Invalid bean definition with name 'dataSource'definedinclass path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]:@Bean definition illegally overridden by existing bean definition:Generic bean:class[com.alipay.zdal.adapter.sofa.spring.ZdalDatasourceFactoryBean]; scope=;abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null

原因

从错误信息来看,或许是 Hikari 包和 ZDAL 包冲突了。

解决方案

假如工程没有使用 Hikari,可以尝试排除 Hikari 包。