Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.ArrayIndexOutOfBoundsException #552

Closed
luyee opened this issue Feb 18, 2014 · 6 comments
Closed

java.lang.ArrayIndexOutOfBoundsException #552

luyee opened this issue Feb 18, 2014 · 6 comments

Comments

@luyee
Copy link

luyee commented Feb 18, 2014

when use the jedis version and Jedispool:

 
 redis.clients
 jedis
 2.1.0

I get this error
java.lang.ArrayIndexOutOfBoundsException: 8211
at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:35)
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:39)
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:33)
at redis.clients.jedis.Connection.sendCommand(Connection.java:80)
at redis.clients.jedis.BinaryClient.set(BinaryClient.java:86)
at redis.clients.jedis.Client.set(Client.java:21)
at redis.clients.jedis.Pipeline.set(Pipeline.java:631)

@HeartSaVioR
Copy link
Contributor

@luyee Hello!
Can you reproduce this issue with latest version (2.4.1)?
We fixed so many things from 2.1.0, so it may help.

And please check Jedis instance does not support multi-threaded environment.
You need to make Jedis_Pool shared across threads and get/return Jedis instance from Jedis_Pool for each thread.
(see #232 for further information)

Also check if you use Jedis*Pool, when Jedis command throws JedisConnectionException, you should do nothing about command and call returnBrokenResource().
(see https://github.com/xetorthio/jedis/wiki/Getting-started#wiki-using-jedis-in-a-multithreaded-environment)

Thanks!

@luyee
Copy link
Author

luyee commented Feb 19, 2014

@HeartSaVioR the same case reproduce in jedis 2.1.0
when this code

        Runnable r = new Runnable(){
            @Override
            public void run() {
                Pipeline p = redisClient.getPipeline();
                 int i = 0;
                    p.set( "indexOutoftest", str );
                    System.out.println(str.length());
                    i++;
                  p.sync();
            }

        };

        for (int i = 0;i<10000; i++) {
            Thread t = new Thread(r);
            t.start();
        }

and the redisClient .getPipeline () use JedisPool

    public Pipeline getPipeline() {
        Pipeline pipeline = null;
        Jedis jedis = null;
        List<String> rsList = null;
        boolean success = true;
        try {
            jedis = this.pool.getResource();
            pipeline = jedis.pipelined();
            return pipeline;
        } catch (JedisException e) {
            success = false;
            if (jedis != null) {
                pool.returnBrokenResource(jedis);
            }
            throw e;
        } finally {
            if (success && jedis != null) {
                this.pool.returnResource(jedis);
            }
        }

    }

@HeartSaVioR
Copy link
Contributor

@luyee Hello!
I confirmed your example code.

At first, your implementation is dangerous.
If jedis.pipelined() is success, getPipeline() returns Pipeline coupled with Jedis instance, but Jedis instance is returned to pool within finally statement in getPipeline().
That means Jedis instance is re-gettable by "another thread" from Pool, while origin thread is using Pipeline.
Jedis instance is not thread-safe.

You should change your implementation to get Jedis instance, get Pipeline, use, sync, return Jedis instance in a row.

@luyee
Copy link
Author

luyee commented Feb 20, 2014

@HeartSaVioR Thx !!!

@HeartSaVioR
Copy link
Contributor

@luyee Can we close this issue? :)

@luyee
Copy link
Author

luyee commented Mar 6, 2014

OK!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants