`
TimerBin
  • 浏览: 359316 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

RunJettyRun 插件使用(spring-data-redis/jedis-2.7.2不兼容)

阅读更多

在Eclipse的RunJettyRun(jetty 7.6.8.v20121106)使用jetty时,在项目中使用到了spring-data-redis-1.5.0.RELEASE.jar、jedis-2.7.2.jar、jedis-2.7.3.jar,于是如以下代码方式访问Redis时:

 

private static RedisTemplate<String, Object> redisTemplate = ...;
redisTemplate.opsForHash().put(CACHE_NAME + key, hashKey, value);

 就会出现如下错误:

 

 

java.lang.ExceptionInInitializerError
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:252)
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:58)
	at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:128)
	at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:91)
	at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:78)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:178)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153)
	at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:86)
	at org.springframework.data.redis.core.DefaultHashOperations.put(DefaultHashOperations.java:169)

.........

java.lang.NullPointerException
	at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:455)
	at org.springframework.data.redis.connection.jedis.JedisConnection.<clinit>(JedisConnection.java:108)
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:252)
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:58)
	at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:128)
	at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:91)
	at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:78)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:178)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153)
	at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:86)
	at org.springframework.data.redis.core.DefaultHashOperations.put(DefaultHashOperations.java:169)

 

 

查源码时发现在进行spring-data-redis-1.5.0.RELEASE.jar包下的JedisConnection类中静态块执行的时候失败报出NullPointerException,源码如下所示:

 

static {
		CLIENT_FIELD = ReflectionUtils.findField(BinaryJedis.class, "client", Client.class);
		ReflectionUtils.makeAccessible(CLIENT_FIELD);
		SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", new Class[] { Command.class,
				byte[][].class });
		ReflectionUtils.makeAccessible(SEND_COMMAND);
		GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class);
		ReflectionUtils.makeAccessible(GET_RESPONSE);
	}

 发现在反射获取Connection的sendCommand方法授权时,出现错误,通过查源码发现问题出现在了jedis-2.7.3.jar、jedis-2.7.2.jar 中的Connection的sendCommand的方法,2.7.2对该方法的Command参数进行了升级,与jedis-2.7.3又将2.7.2的改进还原了,从而不兼容导致初始化错误的出现。

 

其中jedis-2.7.3.jar的 Connection源码如下所示:

 

protected Connection sendCommand(final Command cmd, final String... args) {
		final byte[][] bargs = new byte[args.length][];
		for (int i = 0; i < args.length; i++) {
			bargs[i] = SafeEncoder.encode(args[i]);
		}
		return sendCommand(cmd, bargs);
    }
	public static enum Command {
		PING,.....;

		public final byte[] raw;

		Command() {
			raw = SafeEncoder.encode(this.name());
		}
    }

 

 

其中jedis-2.7.2.jar的 Connection源码如下所示:

 

 protected Connection sendCommand(final ProtocolCommand cmd, final String... args) {
		final byte[][] bargs = new byte[args.length][];
		for (int i = 0; i < args.length; i++) {
		  bargs[i] = SafeEncoder.encode(args[i]);
		}
		return sendCommand(cmd, bargs);
	}
	public static enum Command implements ProtocolCommand {
		PING,..... ERGE;

		private final byte[] raw;

		Command() {
		  raw = SafeEncoder.encode(this.name());
		}

		@Override
		public byte[] getRaw() {
		  return raw;
		}
  }

 

 

 

先说解决办法将spring-data-redis升级到spring-data-redis-1.6.0.RELEASE.jar,其中JedisConnection的静态块如下所示:

 

static {

		CLIENT_FIELD = ReflectionUtils.findField(BinaryJedis.class, "client", Client.class);
		ReflectionUtils.makeAccessible(CLIENT_FIELD);

		try {
			Class<?> commandType = ClassUtils.isPresent("redis.clients.jedis.ProtocolCommand", null) ? ClassUtils.forName(
					"redis.clients.jedis.ProtocolCommand", null) : ClassUtils.forName("redis.clients.jedis.Protocol$Command",
					null);

			SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", new Class[] { commandType,
					byte[][].class });
		} catch (Exception e) {
			throw new NoClassDefFoundError(
					"Could not find required flavor of command required by 'redis.clients.jedis.Connection#sendCommand'.");
		}

		ReflectionUtils.makeAccessible(SEND_COMMAND);

		GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class);
		ReflectionUtils.makeAccessible(GET_RESPONSE);
	}

 关键一点在于反射调用sendCommand方法时对方法的参数进行了类型判断从而防止了错误的产生。

 

 

注:经猜测最终原因可能是jetty在进行类实例化时使用的jedis-2.7.2.jar但是在真正调用时却使用的jedis-2.7.3.jar从而导致错误的产生!

 

 

 

分享到:
评论

相关推荐

    spring-session-data-redis-2.0.4.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-session-data-redis-2.0.4.RELEASE.jar; 赠送原API文档:spring-session-data-redis-2.0.4.RELEASE-javadoc.jar; 赠送源代码:spring-session-data-redis-2.0.4.RELEASE-sources.jar; 赠送...

    spring-data-redis-2.3.9.RELEASE-API文档-中文版.zip

    赠送jar包:spring-data-redis-2.3.9.RELEASE.jar; 赠送原API文档:spring-data-redis-2.3.9.RELEASE-javadoc.jar; 赠送源代码:spring-data-redis-2.3.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...

    spring-data-redis-1.6.0.RELEASE.jar + jedis-2.7.2.jar.rar

    包含Java说明文件、配置代码、redis相应版本的Jar 1、代码片段要求的框架为:SpringMVC,但原理都是一样的,采用其他方式也可以。 2、RedisMng为简单封装的接口,不封装,直接采用redisTemplate也可以。

    spring-session-data-redis-2.0.4.RELEASE-API文档-中文版.zip

    赠送jar包:spring-session-data-redis-2.0.4.RELEASE.jar; 赠送原API文档:spring-session-data-redis-2.0.4.RELEASE-javadoc.jar; 赠送源代码:spring-session-data-redis-2.0.4.RELEASE-sources.jar; 赠送...

    spring-session-redis/spring整合redis管理session依赖jar包

    commons-pool2-2.3.jar,jedis-2.8.0.jar,spring-data-redis-1.6.0.RELEASE.jar,spring-session-1.1.1.RELEASE.jar,Spring-data-redis(Version 1.6.0.RC1)中文版.pdf

    spring-data-redis-1.6.0.RELEASE.jar + jedis-2.7.2.jar

    例如,要使用Spring Data Redis,首先需要在项目中引入`spring-data-redis-1.6.0.RELEASE.jar`。然后,通过配置文件设置Redis服务器的连接信息,包括主机地址、端口、密码等。接着,在Spring的配置类中定义...

    spring-data-redis-2.6.1-API文档-中文版.zip

    赠送jar包:spring-data-redis-2.6.1.jar; 赠送原API文档:spring-data-redis-2.6.1-javadoc.jar; 赠送源代码:spring-data-redis-2.6.1-sources.jar; 赠送Maven依赖信息文件:spring-data-redis-2.6.1.pom; ...

    spring-data-redis-2.0.9.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-data-redis-2.0.9.RELEASE.jar; 赠送原API文档:spring-data-redis-2.0.9.RELEASE-javadoc.jar; 赠送源代码:spring-data-redis-2.0.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...

    spring-data-redis-2.5.5-API文档-中英对照版.zip

    赠送jar包:spring-data-redis-2.5.5.jar; 赠送原API文档:spring-data-redis-2.5.5-javadoc.jar; 赠送源代码:spring-data-redis-2.5.5-sources.jar; 赠送Maven依赖信息文件:spring-data-redis-2.5.5.pom; ...

    spring-data-redis-2.5.5-API文档-中文版.zip

    赠送jar包:spring-data-redis-2.5.5.jar; 赠送原API文档:spring-data-redis-2.5.5-javadoc.jar; 赠送源代码:spring-data-redis-2.5.5-sources.jar; 赠送Maven依赖信息文件:spring-data-redis-2.5.5.pom; ...

    spring-data-redis-2.0.6.RELEASE-API文档-中文版.zip

    赠送jar包:spring-data-redis-2.0.6.RELEASE.jar; 赠送原API文档:spring-data-redis-2.0.6.RELEASE-javadoc.jar; 赠送源代码:spring-data-redis-2.0.6.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...

    spring-data-redis 1.7.6

    10. **源码分析**:`spring-data-redis-1.7.6.RELEASE-sources.jar`包含了源码,对于开发者来说,这是一个宝贵的资源,可以深入理解其内部实现,提高解决问题的能力。 总的来说,Spring Data Redis 1.7.6版本提供了...

    spring-data-redis-1.8.1.RELEASE-sources.jar(源码)

    spring-data-redis-1.8.1.RELEASE-sources.jar(spring-data-redis-1.8.1.RELEASE-sources.jar()

    spring-data-redis-1.6.0.RELEASE.jar + jedis-2.7.2.jar包

    综上所述,"spring-data-redis-1.6.0.RELEASE.jar + jedis-2.7.2.jar"组合提供了Spring应用程序与Redis交互的强大工具集,涵盖了从基本操作到复杂应用场景的各种功能。在实际开发中,你需要根据项目需求选择合适的...

    Spring Data Redis

    Spring Data Redis 纯英文文档,介绍spring操作redis的一些用法

    spring-data-redis-1.7.5.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-data-redis-1.7.5.RELEASE.jar 赠送原API文档:spring-data-redis-1.7.5.RELEASE-javadoc.jar 赠送源代码:spring-data-redis-1.7.5.RELEASE-sources.jar 包含翻译后的API文档:spring-data-...

    spring-data-redis-2.0.9.RELEASE-API文档-中文版.zip

    赠送jar包:spring-data-redis-2.0.9.RELEASE.jar; 赠送原API文档:spring-data-redis-2.0.9.RELEASE-javadoc.jar; 赠送源代码:spring-data-redis-2.0.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...

    spring-data-redis2.jar

    spring-data-redis-2.0.0.M1.jar

    springMVC集成spring-data-redis

    而Spring Data Redis是Spring Framework的一个模块,专门用于简化与Redis键值存储系统的交互。Redis是一个高性能的、开源的、支持网络的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 在...

    spring-data-redis-2.6.1-API文档-中英对照版.zip

    赠送jar包:spring-data-redis-2.6.1.jar; 赠送原API文档:spring-data-redis-2.6.1-javadoc.jar; 赠送源代码:spring-data-redis-2.6.1-sources.jar; 赠送Maven依赖信息文件:spring-data-redis-2.6.1.pom; ...

Global site tag (gtag.js) - Google Analytics