Skip to content

Commit e98dd0d

Browse files
committed
fix #43: Prevent ClassCastExceptions after plugin gets reloaded in a cluster
This plugin caches instances of classes that are defined in the code of the plugin. This causes ClassCastExceptions, when the plugin gets unloaded (removing the class definitions) and updated/reloaded (replacing the class definitions). The cached values at that time will refer to classes that no longer exist, causing the exceptions. https://igniterealtime.atlassian.net/browse/OF-2239 introduces a new type of Cache to work around this problem, the org.jivesoftware.util.cache.SerializingCache which is available since Openfire 4.7.0. This implementation does not cache the instance directly, but caches a serialized version instead. This way, there no longer is a reference to the class, which means that any (compatible) future class definition can be used to instantiate the cache entry again. Openfire 4.8.1 introduces fixes for the SerializingCache implementation: - https://igniterealtime.atlassian.net/browse/OF-2781 - https://igniterealtime.atlassian.net/browse/OF-2782 This commit updates the minimum required version of Openfire to 4.8.1, to be able to make use of these fixes.
1 parent e19c954 commit e98dd0d

File tree

4 files changed

+17
-10
lines changed

4 files changed

+17
-10
lines changed

changelog.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141

4242
<h1>HTTP File Upload Plugin Changelog</h1>
4343

44+
<p><b>1.5.0</b> -- (tbd)</p>
45+
<ul>
46+
<li>Now requires Openfire 4.8.1 or later</li>
47+
<li><a href="https://github.com/igniterealtime/openfire-httpFileUpload-plugin/issues/43">Issue #43:</a> ClassCastExceptions after reloading plugin in a cluster.</li>
48+
</ul>
49+
4450
<p><b>1.4.2</b> -- (November 19, 2024)</p>
4551
<ul>
4652
<li>Updated Chinese (zh_CN) translation</li>

plugin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<author>Guus der Kinderen</author>
77
<version>${project.version}</version>
88
<date>2024-11-19</date>
9-
<minServerVersion>4.7.0</minServerVersion>
9+
<minServerVersion>4.8.1</minServerVersion>
1010
<priorToServerVersion>5.0.0</priorToServerVersion>
1111
<minJavaVersion>1.8</minJavaVersion>
1212
<csrfProtectionEnabled>true</csrfProtectionEnabled>

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
<parent>
55
<artifactId>plugins</artifactId>
66
<groupId>org.igniterealtime.openfire</groupId>
7-
<version>4.7.0</version>
7+
<version>4.8.1</version>
88
</parent>
99
<groupId>org.igniterealtime.openfire.plugins</groupId>
1010
<artifactId>httpfileupload</artifactId>
1111
<name>HTTP File Upload Plugin</name>
1212
<description>Allows clients to share files, as described in the XEP-0363 'HTTP File Upload' specification.</description>
13-
<version>1.4.3-SNAPSHOT</version>
13+
<version>1.5.0-SNAPSHOT</version>
1414

1515
<distributionManagement>
1616
<!-- Repository in which we deploy this project, when desired. -->

src/java/org/igniterealtime/openfire/plugins/httpfileupload/OpenfireSlotProvider.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2022 Ignite Realtime Foundation. All rights reserved.
2+
* Copyright (c) 2017-2024 Ignite Realtime Foundation. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,10 +29,11 @@
2929

3030
public class OpenfireSlotProvider implements SlotProvider
3131
{
32-
private final Cache<SecureUniqueId, Slot> slotsCache;
32+
// Use string-representation of SecureUniqueId as cache key, as the interface cannot be processed by JAXB.
33+
private final Cache<String, Slot> slotsCache;
3334

3435
public OpenfireSlotProvider() {
35-
slotsCache = CacheFactory.createCache("HTTP File Upload Slots");
36+
slotsCache = CacheFactory.createSerializingCache("HTTP File Upload Slots", String.class, Slot.class);
3637

3738
// Unless there is specific configuration for this cache, default the max lifetime of entries in this cache to something that's fairly short.
3839
if (null == JiveGlobals.getProperty("cache." + slotsCache.getName().replaceAll(" ", "") + ".maxLifetime")) {
@@ -43,10 +44,10 @@ public OpenfireSlotProvider() {
4344
@Override
4445
public void create(@Nonnull final Slot slot)
4546
{
46-
final Lock lock = slotsCache.getLock(slot.getUuid());
47+
final Lock lock = slotsCache.getLock(slot.getUuid().toString());
4748
lock.lock();
4849
try {
49-
slotsCache.put( slot.getUuid(), slot );
50+
slotsCache.put( slot.getUuid().toString(), slot );
5051
} finally {
5152
lock.unlock();
5253
}
@@ -56,10 +57,10 @@ public void create(@Nonnull final Slot slot)
5657
@Override
5758
public Slot consume(@Nonnull final SecureUniqueId slotId)
5859
{
59-
final Lock lock = slotsCache.getLock(slotId);
60+
final Lock lock = slotsCache.getLock(slotId.toString());
6061
lock.lock();
6162
try {
62-
return slotsCache.remove(slotId);
63+
return slotsCache.remove(slotId.toString());
6364
} finally {
6465
lock.unlock();
6566
}

0 commit comments

Comments
 (0)