INT-3907: Downgrade to Kryo-2.22
JIRA: https://jira.spring.io/browse/INT-3907 The IO-1.1.x is based on the Kryo-2.22 and can't be upgraded to 3.0. Therefore we should downgrade. * Change `PojoCodec` to use `StdInstantiatorStrategy` directly, because the `DefaultInstantiatorStrategy` logic is as a core code of `Kryo`. * Introduce `org.springframework.integration.codec.kryo.pool` package and copy/paste `com.esotericsoftware.kryo.pool` classes, since they have been introduced since Kryo-3.0. * That copy/paste seemed to me the simplest fix, since the `KryoPool` logic is encapsulated in the `AbstractKryoCodec`
This commit is contained in:
committed by
Gary Russell
parent
2dfdfee95e
commit
a91518c97b
@@ -106,7 +106,7 @@ subprojects { subproject ->
|
||||
jsonpathVersion = '0.9.1'
|
||||
junitVersion = '4.11'
|
||||
jythonVersion = '2.5.3'
|
||||
kryoShadedVersion = '3.0.3'
|
||||
kryoVersion = '2.22'
|
||||
log4jVersion = '1.2.17'
|
||||
mockitoVersion = '1.9.5'
|
||||
mysqlVersion = '5.1.29'
|
||||
@@ -268,7 +268,7 @@ project('spring-integration-core') {
|
||||
compile("com.fasterxml.jackson.core:jackson-databind:$jackson2Version", optional)
|
||||
compile("com.jayway.jsonpath:json-path:$jsonpathVersion", optional)
|
||||
compile("io.fastjson:boon:$boonVersion", optional)
|
||||
compile("com.esotericsoftware:kryo-shaded:$kryoShadedVersion", optional)
|
||||
compile("com.esotericsoftware.kryo:kryo:$kryoVersion", optional)
|
||||
|
||||
testCompile ("org.aspectj:aspectjweaver:$aspectjVersion")
|
||||
testCompile ("net.openhft:chronicle:$chronicleVersion")
|
||||
|
||||
@@ -22,14 +22,14 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.springframework.integration.codec.Codec;
|
||||
import org.springframework.integration.codec.kryo.pool.KryoCallback;
|
||||
import org.springframework.integration.codec.kryo.pool.KryoFactory;
|
||||
import org.springframework.integration.codec.kryo.pool.KryoPool;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
import com.esotericsoftware.kryo.io.Input;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
import com.esotericsoftware.kryo.pool.KryoCallback;
|
||||
import com.esotericsoftware.kryo.pool.KryoFactory;
|
||||
import com.esotericsoftware.kryo.pool.KryoPool;
|
||||
|
||||
/**
|
||||
* Base class for {@link Codec}s using {@link Kryo}.
|
||||
|
||||
@@ -19,13 +19,12 @@ package org.springframework.integration.codec.kryo;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.objenesis.strategy.StdInstantiatorStrategy;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
import com.esotericsoftware.kryo.io.Input;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
import com.esotericsoftware.shaded.org.objenesis.strategy.StdInstantiatorStrategy;
|
||||
|
||||
/**
|
||||
* Kryo Codec that can encode and decode arbitrary types. Classes and associated
|
||||
@@ -99,7 +98,7 @@ public class PojoCodec extends AbstractKryoCodec {
|
||||
|
||||
@Override
|
||||
protected void configureKryoInstance(Kryo kryo) {
|
||||
kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));
|
||||
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
|
||||
if (this.kryoRegistrar != null) {
|
||||
this.kryoRegistrar.registerTypes(kryo);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.codec.kryo.pool;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
|
||||
/**
|
||||
* Callback to run with a provided kryo instance.
|
||||
* <p>
|
||||
* Copied from Kryo 3.0 to facilitate dropping back to 2.22 for Spring IO
|
||||
* compatibility.
|
||||
*
|
||||
* @author Martin Grotzke
|
||||
*
|
||||
* @param <T> The type of the result of the interaction with kryo.
|
||||
*/
|
||||
public interface KryoCallback<T> {
|
||||
|
||||
T execute(Kryo kryo);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.codec.kryo.pool;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
|
||||
/**
|
||||
* Factory to create new configured instances of {@link Kryo}.
|
||||
* <p>
|
||||
* Copied from Kryo 3.0 to facilitate dropping back to 2.22 for Spring IO
|
||||
* compatibility.
|
||||
*
|
||||
* @author Martin Grotzke
|
||||
*/
|
||||
public interface KryoFactory {
|
||||
|
||||
Kryo create();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.codec.kryo.pool;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
|
||||
/**
|
||||
* A simple pool interface for {@link Kryo} instances. Use the {@link KryoPool.Builder} to
|
||||
* construct a pool instance.
|
||||
* <p>
|
||||
* Copied from Kryo 3.0 to facilitate dropping back to 2.22 for Spring IO
|
||||
* compatibility.
|
||||
* <p>
|
||||
* Usage:
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
*
|
||||
* KryoFactory factory = new KryoFactory() {
|
||||
* public Kryo create () {
|
||||
* Kryo kryo = new Kryo();
|
||||
* // configure kryo instance, customize settings
|
||||
* return kryo;
|
||||
* }
|
||||
* };
|
||||
* // Simple pool, you might also activate SoftReferences to fight OOMEs.
|
||||
* KryoPool pool = new KryoPool.Builder(factory).build();
|
||||
* Kryo kryo = pool.borrow();
|
||||
* // do s.th. with kryo here, and afterwards release it
|
||||
* pool.release(kryo);
|
||||
*
|
||||
* // or use a callback to work with kryo (pool.run borrows+releases for you)
|
||||
* String value = pool.run(new KryoCallback<String>() {
|
||||
* public String execute(Kryo kryo) {
|
||||
* return kryo.readObject(input, String.class);
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
* @author Martin Grotzke
|
||||
*/
|
||||
public interface KryoPool {
|
||||
|
||||
/**
|
||||
* Takes a {@link Kryo} instance from the pool or creates a new one
|
||||
* (using the factory) if the pool is empty.
|
||||
* @return the {@link Kryo} instance.
|
||||
*/
|
||||
Kryo borrow();
|
||||
|
||||
/**
|
||||
* Returns the given {@link Kryo} instance to the pool.
|
||||
* @param kryo the {@link Kryo} instance to release.
|
||||
*/
|
||||
void release(Kryo kryo);
|
||||
|
||||
/**
|
||||
* Runs the provided {@link KryoCallback} with a {@link Kryo} instance
|
||||
* from the pool (borrow/release around {@link KryoCallback#execute(Kryo)}).
|
||||
* @param callback the {@link KryoCallback} to call.
|
||||
* @param <T> The type of the result of the interaction with kryo.
|
||||
* @return the result of the interaction with {@link Kryo}.
|
||||
*/
|
||||
<T> T run(KryoCallback<T> callback);
|
||||
|
||||
/**
|
||||
* Builder for a {@link KryoPool} instance, constructs a {@link KryoPoolQueueImpl} instance.
|
||||
*/
|
||||
class Builder {
|
||||
|
||||
private final KryoFactory factory;
|
||||
|
||||
private Queue<Kryo> queue = new ConcurrentLinkedQueue<Kryo>();
|
||||
|
||||
private boolean softReferences;
|
||||
|
||||
public Builder(KryoFactory factory) {
|
||||
if (factory == null) {
|
||||
throw new IllegalArgumentException("factory must not be null");
|
||||
}
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given queue for pooling kryo instances (by default a {@link ConcurrentLinkedQueue}
|
||||
* is used).
|
||||
* @param queue the queue instance to use.
|
||||
* @return the Builder instance.
|
||||
*/
|
||||
public Builder queue(Queue<Kryo> queue) {
|
||||
if (queue == null) {
|
||||
throw new IllegalArgumentException("queue must not be null");
|
||||
}
|
||||
this.queue = queue;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link SoftReference}s for pooled {@link Kryo} instances, so that
|
||||
* instances may be garbage collected when there's memory demand (by default
|
||||
* disabled).
|
||||
* @return the Builder instance.
|
||||
*/
|
||||
public Builder softReferences() {
|
||||
softReferences = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the pool.
|
||||
* @return the KryoPool instance.
|
||||
*/
|
||||
public KryoPool build() {
|
||||
Queue<Kryo> q = softReferences ? new SoftReferenceQueue(queue) : queue;
|
||||
return new KryoPoolQueueImpl(factory, q);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + "[queue.class=" + queue.getClass() +
|
||||
", softReferences=" + softReferences + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.codec.kryo.pool;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
|
||||
/**
|
||||
* A simple {@link Queue} based {@link KryoPool} implementation, should be built
|
||||
* using the KryoPool.Builder.
|
||||
* <p>
|
||||
* Copied from Kryo 3.0 to facilitate dropping back to 2.22 for Spring IO
|
||||
* compatibility.
|
||||
* @author Martin Grotzke
|
||||
*/
|
||||
class KryoPoolQueueImpl implements KryoPool {
|
||||
|
||||
private final Queue<Kryo> queue;
|
||||
|
||||
private final KryoFactory factory;
|
||||
|
||||
KryoPoolQueueImpl(KryoFactory factory, Queue<Kryo> queue) {
|
||||
this.factory = factory;
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kryo borrow() {
|
||||
Kryo res;
|
||||
if ((res = queue.poll()) != null) {
|
||||
return res;
|
||||
}
|
||||
return factory.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(Kryo kryo) {
|
||||
queue.offer(kryo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T run(KryoCallback<T> callback) {
|
||||
Kryo kryo = borrow();
|
||||
try {
|
||||
return callback.execute(kryo);
|
||||
}
|
||||
finally {
|
||||
release(kryo);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
queue.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.codec.kryo.pool;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Queue;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
|
||||
/**
|
||||
* Internally uses {@link SoftReference}s for queued Kryo instances,
|
||||
* most importantly adjusts the {@link Queue#poll() poll}
|
||||
* behavior so that gc'ed Kryo instances are skipped.
|
||||
* Most other methods are unsupported.
|
||||
* <p>
|
||||
* Copied from Kryo 3.0 to facilitate dropping back to 2.22 for Spring IO
|
||||
* compatibility.
|
||||
* @author Martin Grotzke
|
||||
*/
|
||||
class SoftReferenceQueue implements Queue<Kryo> {
|
||||
|
||||
private final Queue<SoftReference<Kryo>> delegate;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public SoftReferenceQueue(Queue<?> delegate) {
|
||||
this.delegate = (Queue<SoftReference<Kryo>>) delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kryo poll() {
|
||||
Kryo res;
|
||||
SoftReference<Kryo> ref;
|
||||
while ((ref = delegate.poll()) != null) {
|
||||
if ((res = ref.get()) != null) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offer(Kryo e) {
|
||||
return delegate.offer(new SoftReference<Kryo>(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Kryo e) {
|
||||
return delegate.add(new SoftReference<Kryo>(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return delegate.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return delegate.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
delegate.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return delegate.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Kryo> iterator() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kryo remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kryo element() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kryo peek() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends Kryo> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* The <a href="https://code.google.com/p/kryo/">Kryo Pool</a> classes.
|
||||
* Copy/paste from Kryo 3.0
|
||||
*/
|
||||
package org.springframework.integration.codec.kryo.pool;
|
||||
Reference in New Issue
Block a user