JAVA7环境下Spring容器对locale对象反序列的bug。

Spring中对于对象的反序化时,需要调用readResolve方法来校验对象的完整性。对于java6的Locale对象,具体实现

private Object readResolve() throws java.io.ObjectStreamException {
        return getInstance(language, country, variant);
}

没有问题。但是对于JAVA7的实

private Object readResolve() throws java.io.ObjectStreamException {
           return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
                  baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
}

我们知道调用readResolve 方法的Locale对象是spring框架中hessian实现,是通过sun.misc.UnSafe的allocateInstance方法用本地码在内存中直接生成,然后通过readObject(AbstractHessianInput in, Object obj,String[] fieldNames)将值赋给这个对象的字段,并没有调用对象的new 方法来进行构造,说白了就是没有通过java常规的构造方法来构造 。那么问题来了。

在java7中,Locale的baseLocale字段是一个transient字段,不会被序列化,它是在对象构造方法中根据其它几个字段动态构造的。

public Locale(String language, String country, String variant) {
            if (language== null || country == null || variant == null) {
               	throw new NullPointerException();
            }
            baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
            localeExtensions = getCompatibilityExtensions(language, "", country, variant);
}

所以通过上面spring的实现方式,调用readResolve对象的Locale对象的baseLocale字段不可能被初始化,只能是null,所以

return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
                  baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);

这里一定会抛出空指针异常。

时间: 2024-11-07 14:54:09

JAVA7环境下Spring容器对locale对象反序列的bug。的相关文章

Quartz与Spring集成 Job如何自动注入Spring容器托管的对象

在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法可以是普通类.很显然,第二种方式远比第一种方式来的灵活. 测试环境 Spring3 M2 quartz-2.1.7 我们要达到这样的效果 public class CancelUnpaidOrderTask implements Job { @Autowired private AppOrderService orderService; @Over

Myeclipse 10 环境下 Spring 框架的使用

环境:MyEclipse 10 版本 Spring框架的使用: 1.建立WEB Project 项目: 2.通过Myeclipse 10 导入Spring框架: 这个步骤需要把Spring 相关的 JAR 包勾选上,并且将配置文件放在WEB-INF目录下,命名为 dispatcherServlet-servlet.xml: 为了以后的方便,这里九江spring 的配置文件命名为了dispatcherServlet-servlet.xml,这个配置文件的名称中的前半部分是在web.xml中声明的s

并发环境下,不安全发布对象示例代码

package com.mm.concurrent; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestConcurrent { public static 

Spring的IOC、Spring对象初始化bean时机、Spring容器生命周期

IOC指的是控制反转,把对象的创建.初始化.销毁等工作都交给Spring容器.由spring容器来控制对象的生命周期. Spring对象初始化bean时机: 在默认情况下,只要在Spring容器中配置了一个bean,容器在启动时就会实例化该bean,单例模式. 如果在Spring配制文件时设置懒加载模式(lazy-init="true"),在getBean时才会实例化对象. 如果scope="prototype"时,无论lazy-init的值是什么都只会在使用时才会

获取Spring容器Bean对象工具类

在开发中,总是能碰到用注解注入不了Spring容器里面bean对象的问题.为了解决这个问题,我们需要一个工具类来直接获取Spring容器中的bean.因此就写了这个工具类,在此记录一下,方便后续查阅.废话不多说,直接上代码. 一.代码 package com.zxy.demo.spring; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext;

获取spring容器对象方法和原因

为什么要获取Spring容器对象:拿到spring容器对象后,你就可以用spring管理的bean了,拿到bean,自然可以使用bean的方法,场景:比如jsp页面.通过注解是无法注入bean的,在开发中,总是能碰到用注解注入不了Spring容器里面bean对象的问题.为了解决这个问题,我们需要一个工具类来直接获取Spring容器中的bean.spring提供了一个工具类WebApplicationContextUtils,就可以拿到了 样例:比如我们项目的代码,在jsp中: 原文地址:http

Spring容器启动过程

搞了一年多的Java了,每个项目都在用Spring,这几天没事看了看Spring源码,总结了下Spring容器的启动过程,想把它记录下来,免得忘了 spring容器的启动方式有两种: 1.自己提供ApplicationContext自己创建Spring容器 2.Web项目中在web.xml中配置监听启动 org.springframework.web.context.ContextLoaderListener 先介绍第一种(自创建) ClassPathXmlApplicationContext 

设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题

设计模式--单例模式(Java)--考虑多线程环境下的线程安全问题 一:单例模式概念 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例 二:单例模式的实现方式 特别注意,在多线程环境下,需要对获取对象实例的方法加对象锁(synchronized) 方式一:(懒汉式)程序执行过程中需要这个类的对象,再实例化这个类的对象 步骤: 1.定义静态私有对象 2.构造方法私有化保证在类的外部无法实例化该类的对象 3.定义对外开放的静

ssh下:系统初始化实现ServletContextListener接口时,获取spring中数据层对象无效的问题

想要实现的功能:SSH环境下,数据层都交由Spring管理:在服务启动时,将数据库中的一些数据加载到ServletContext中缓存起来. 系统初始化类需要实现两个接口: ServletContextListener,系统初始化时调用contextInitialized方法缓存数据: ApplicationContextAware,获取Spring的ApplicationContext对象,以获取spring容器管理的service对象. 系统初始化类如下: 1 package com.liz