diff --git a/javadoc/pom.xml b/javadoc/pom.xml
index 8b565fdaf08..2c62408af29 100644
--- a/javadoc/pom.xml
+++ b/javadoc/pom.xml
@@ -419,6 +419,12 @@
infinispan-core
${infinispan.version}
provided
+
+
+ org.wildfly.common
+ wildfly-common
+
+
@@ -431,7 +437,7 @@
org.infinispan.protostream
protostream
- 4.2.2.Final
+ ${infinispan.protostream.version}
provided
diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml
index f4bca94018c..0d370408b61 100644
--- a/jetty-home/pom.xml
+++ b/jetty-home/pom.xml
@@ -746,6 +746,12 @@
${project.version}
pom
true
+
+
+ org.wildfly.common
+ *
+
+
org.eclipse.jetty
diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml
index 5ae82c3b0b7..466498b7c0f 100644
--- a/jetty-infinispan/infinispan-common/pom.xml
+++ b/jetty-infinispan/infinispan-common/pom.xml
@@ -37,8 +37,13 @@
org.infinispan
infinispan-core
- ${infinispan.version}
true
+
+
+ org.wildfly.common
+ wildfly-common
+
+
org.infinispan.protostream
@@ -63,13 +68,11 @@
org.infinispan
infinispan-client-hotrod
- ${infinispan.version}
provided
org.infinispan
infinispan-remote-query-client
- ${infinispan.version}
provided
diff --git a/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml b/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml
index 95ef9c854f1..0092a534815 100644
--- a/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml
+++ b/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml
@@ -10,6 +10,7 @@
+
diff --git a/jetty-infinispan/infinispan-common/src/main/config/modules/sessions/infinispan/infinispan-common.mod b/jetty-infinispan/infinispan-common/src/main/config/modules/sessions/infinispan/infinispan-common.mod
index 02a77867610..d2a400bdbd8 100644
--- a/jetty-infinispan/infinispan-common/src/main/config/modules/sessions/infinispan/infinispan-common.mod
+++ b/jetty-infinispan/infinispan-common/src/main/config/modules/sessions/infinispan/infinispan-common.mod
@@ -13,7 +13,7 @@ lib/infinispan-common-${jetty.version}.jar
lib/infinispan/*.jar
[ini]
-infinispan.version?=9.4.8.Final
+infinispan.version?=11.0.11.Final
[license]
Infinispan is an open source project hosted on Github and released under the Apache 2.0 license.
diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java
new file mode 100644
index 00000000000..352ac535775
--- /dev/null
+++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java
@@ -0,0 +1,51 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.session.infinispan;
+
+import java.io.UncheckedIOException;
+
+import org.infinispan.protostream.FileDescriptorSource;
+import org.infinispan.protostream.SerializationContext;
+import org.infinispan.protostream.SerializationContextInitializer;
+
+/**
+ * Set up the marshaller for InfinispanSessionData serialization
+ *
+ */
+public class InfinispanSerializationContextInitializer implements SerializationContextInitializer
+{
+ @Override
+ public String getProtoFileName()
+ {
+ return "session.proto";
+ }
+
+ @Override
+ public String getProtoFile() throws UncheckedIOException
+ {
+ return FileDescriptorSource.getResourceAsString(getClass(), "/" + getProtoFileName());
+ }
+
+ @Override
+ public void registerSchema(SerializationContext serCtx)
+ {
+ serCtx.registerProtoFiles(FileDescriptorSource.fromString(getProtoFileName(), getProtoFile()));
+ }
+
+ @Override
+ public void registerMarshallers(SerializationContext serCtx)
+ {
+ serCtx.registerMarshaller(new SessionDataMarshaller());
+ }
+}
diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java
index 614e518bea0..12c80895b9d 100644
--- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java
+++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java
@@ -33,7 +33,6 @@ import org.infinispan.commons.marshall.SerializeWith;
* pool and thus these threads have no knowledge of the correct classloader to
* use.
*/
-@SerializeWith(SessionDataMarshaller.class)
public class InfinispanSessionData extends SessionData
{
protected byte[] _serializedAttributes;
diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
index fa4ddeeed80..823d029d428 100644
--- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
+++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
@@ -44,6 +44,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
private int _infinispanIdleTimeoutSec;
private QueryManager _queryManager;
private boolean _passivating;
+ private boolean _serialization;
/**
* Get the clustered cache instance.
@@ -74,9 +75,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
try
{
- _passivating = false;
Class> remoteClass = InfinispanSessionDataStore.class.getClassLoader().loadClass("org.infinispan.client.hotrod.RemoteCache");
- if (remoteClass.isAssignableFrom(_cache.getClass()))
+ if (remoteClass.isAssignableFrom(_cache.getClass()) || _serialization)
_passivating = true;
}
catch (ClassNotFoundException e)
@@ -105,6 +105,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
LOG.debug("Loading session {} from infinispan", id);
InfinispanSessionData sd = _cache.get(getCacheKey(id));
+
+ //Deserialize the attributes now that we are back in a thread that
+ //has the correct classloader set on it
if (isPassivating() && sd != null)
{
if (LOG.isDebugEnabled())
@@ -205,6 +208,15 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
+ //prepare for serialization: we need to convert the attributes now while the context
+ //classloader is set, because infinispan uses a different thread and classloader to
+ //perform the serialization
+ if (isPassivating() && data != null)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Serializing session attributes for {}", id);
+ ((InfinispanSessionData)data).serializeAttributes();
+ }
//Put an idle timeout on the cache entry if the session is not immortal -
//if no requests arrive at any node before this timeout occurs, or no node
//scavenges the session before this timeout occurs, the session will be removed.
@@ -270,6 +282,11 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
{
return _infinispanIdleTimeoutSec;
}
+
+ public void setSerialization(boolean serialization)
+ {
+ _serialization = serialization;
+ }
@Override
public String toString()
diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java
index f16c257d10e..fd3fa839436 100644
--- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java
+++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java
@@ -26,6 +26,7 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF
int _infinispanIdleTimeoutSec;
BasicCache _cache;
protected QueryManager _queryManager;
+ protected boolean _serialization;
/**
* @return the infinispanIdleTimeoutSec
@@ -52,6 +53,7 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF
store.setCache(getCache());
store.setSavePeriodSec(getSavePeriodSec());
store.setQueryManager(getQueryManager());
+ store.setSerialization(getSerialization());
return store;
}
@@ -84,4 +86,14 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF
{
_queryManager = queryManager;
}
+
+ public void setSerialization(boolean serialization)
+ {
+ _serialization = serialization;
+ }
+
+ public boolean getSerialization()
+ {
+ return _serialization;
+ }
}
diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java
index 31036998382..7e0941b01e6 100644
--- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java
+++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java
@@ -14,10 +14,7 @@
package org.eclipse.jetty.session.infinispan;
import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.protostream.FileDescriptorSource;
import org.infinispan.protostream.MessageMarshaller;
import org.infinispan.protostream.ProtobufUtil;
@@ -31,8 +28,7 @@ import org.infinispan.protostream.SerializationContext;
* control to ensure that session attributes can be deserialized using either
* the container class loader or the webapp classloader, as appropriate.
*/
-public class SessionDataMarshaller
- implements MessageMarshaller, Externalizer
+public class SessionDataMarshaller implements MessageMarshaller
{
/**
* The version of the serializer.
@@ -67,39 +63,6 @@ public class SessionDataMarshaller
return "org_eclipse_jetty_session_infinispan.InfinispanSessionData";
}
- @Override
- public InfinispanSessionData readObject(ObjectInput input) throws IOException, ClassNotFoundException
- {
- if (serializationContext == null)
- {
- initSerializationContext();
- }
-
- // invokes readFrom(ProtoStreamReader)
- InfinispanSessionData data = ProtobufUtil.readFrom(serializationContext, new BoundDelegatingInputStream(input),
- InfinispanSessionData.class);
- if (data != null)
- {
- data.deserializeAttributes();
- }
- return data;
- }
-
- @Override
- public void writeObject(ObjectOutput output, InfinispanSessionData object) throws IOException
- {
- if (serializationContext == null)
- {
- initSerializationContext();
- }
-
- // invokes writeTo(ProtoStreamWriter, InfinispanSessionData)
- byte[] data = ProtobufUtil.toByteArray(serializationContext, object);
- int length = data.length;
- output.writeInt(length);
- output.write(data);
- }
-
@Override
public InfinispanSessionData readFrom(ProtoStreamReader in) throws IOException
{
@@ -127,6 +90,9 @@ public class SessionDataMarshaller
if (version == 0)
{
byte[] attributeArray = in.readBytes("attributes");
+ //only save the serialized bytes here, do NOT deserialize because
+ //infinispan has called this method with their own thread without
+ //the appropriate classloader being set
sd.setSerializedAttributes(attributeArray);
return sd;
}
@@ -152,7 +118,9 @@ public class SessionDataMarshaller
out.writeLong("expiry", sdata.getExpiry());
out.writeLong("maxInactiveMs", sdata.getMaxInactiveMs());
- sdata.serializeAttributes();
+ //the session data attributes MUST be previously serialized
+ //because this method is called from an infinispan thread that cannot
+ //have the appropriate classloader set on it
out.writeBytes("attributes", sdata.getSerializedAttributes());
}
diff --git a/jetty-infinispan/infinispan-embedded-query/pom.xml b/jetty-infinispan/infinispan-embedded-query/pom.xml
index 5bf2776ea1e..05a179acdf1 100644
--- a/jetty-infinispan/infinispan-embedded-query/pom.xml
+++ b/jetty-infinispan/infinispan-embedded-query/pom.xml
@@ -106,7 +106,6 @@
org.infinispan
infinispan-query
- ${infinispan.version}
org.eclipse.jetty.toolchain
diff --git a/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java b/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java
index a91c1208a75..12319d10c0f 100644
--- a/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java
+++ b/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java
@@ -22,6 +22,7 @@ import org.infinispan.Cache;
import org.infinispan.query.Search;
import org.infinispan.query.dsl.Query;
import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.dsl.QueryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,39 +33,40 @@ public class EmbeddedQueryManager implements QueryManager
private static final Logger LOG = LoggerFactory.getLogger(EmbeddedQueryManager.class);
private Cache _cache;
+ private QueryFactory _factory;
public EmbeddedQueryManager(Cache cache)
{
_cache = cache;
+ _factory = Search.getQueryFactory(_cache);
}
@Override
public Set queryExpiredSessions(SessionContext sessionContext, long time)
{
Objects.requireNonNull(sessionContext);
- QueryFactory qf = Search.getQueryFactory(_cache);
- Query q = qf.from(InfinispanSessionData.class)
- .select("id")
- .having("contextPath").eq(sessionContext.getCanonicalContextPath())
- .and()
- .having("expiry").lte(time)
- .and().having("expiry").gt(0)
- .build();
-
- List