Modernize sal-akka-raft 29/103529/2
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 2 Dec 2022 16:17:54 +0000 (17:17 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 2 Dec 2022 16:52:25 +0000 (17:52 +0100)
Use instanceof and switch expressions to improve code flows. Also
shortcut handleRequestVote(), as we can have the instance casted
in AbstractLeader.

Change-Id: Ib726c79fbcc667335a3749f528b3836dc3896e73
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorDelegatingPersistentDataProvider.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorLeadershipTransferCohort.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorRecoverySupport.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupport.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupport.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractLeader.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehavior.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/ServerInfo.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntrySerializer.java

index 67fc8b5b45c34ca6a032d1f15b3ea7727450316b..a1e94bd836213b07d65d38ce880918197ff9a3a1 100644 (file)
@@ -228,9 +228,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
         if (snapshotSupport.handleSnapshotMessage(message, getSender())) {
             return;
         }
-        if (message instanceof ApplyState) {
-            ApplyState applyState = (ApplyState) message;
-
+        if (message instanceof ApplyState applyState) {
             if (!hasFollowers()) {
                 // for single node, the capture should happen after the apply state
                 // as we delete messages from the persistent journal which have made it to the snapshot
@@ -242,8 +240,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
             }
 
             possiblyHandleBehaviorMessage(message);
-        } else if (message instanceof ApplyJournalEntries) {
-            ApplyJournalEntries applyEntries = (ApplyJournalEntries) message;
+        } else if (message instanceof ApplyJournalEntries applyEntries) {
             LOG.debug("{}: Persisting ApplyJournalEntries with index={}", persistenceId(), applyEntries.getToIndex());
 
             persistence().persistAsync(applyEntries, NoopProcedure.instance());
@@ -253,24 +250,24 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
             onGetOnDemandRaftStats();
         } else if (message instanceof InitiateCaptureSnapshot) {
             captureSnapshot();
-        } else if (message instanceof SwitchBehavior) {
-            switchBehavior((SwitchBehavior) message);
-        } else if (message instanceof LeaderTransitioning) {
-            onLeaderTransitioning((LeaderTransitioning)message);
+        } else if (message instanceof SwitchBehavior switchBehavior) {
+            switchBehavior(switchBehavior);
+        } else if (message instanceof LeaderTransitioning leaderTransitioning) {
+            onLeaderTransitioning(leaderTransitioning);
         } else if (message instanceof Shutdown) {
             onShutDown();
-        } else if (message instanceof Runnable) {
-            ((Runnable)message).run();
-        } else if (message instanceof NoopPayload) {
-            persistData(null, null, (NoopPayload) message, false);
-        } else if (message instanceof RequestLeadership) {
-            onRequestLeadership((RequestLeadership) message);
+        } else if (message instanceof Runnable runnable) {
+            runnable.run();
+        } else if (message instanceof NoopPayload noopPayload) {
+            persistData(null, null, noopPayload, false);
+        } else if (message instanceof RequestLeadership requestLeadership) {
+            onRequestLeadership(requestLeadership);
         } else if (!possiblyHandleBehaviorMessage(message)) {
-            if (message instanceof JournalProtocol.Response
-                && delegatingPersistenceProvider.handleJournalResponse((JournalProtocol.Response) message)) {
+            if (message instanceof JournalProtocol.Response response
+                && delegatingPersistenceProvider.handleJournalResponse(response)) {
                 LOG.debug("{}: handled a journal response", persistenceId());
-            } else if (message instanceof SnapshotProtocol.Response
-                && delegatingPersistenceProvider.handleSnapshotResponse((SnapshotProtocol.Response) message)) {
+            } else if (message instanceof SnapshotProtocol.Response response
+                && delegatingPersistenceProvider.handleSnapshotResponse(response)) {
                 LOG.debug("{}: handled a snapshot response", persistenceId());
             } else {
                 handleNonRaftCommand(message);
@@ -484,11 +481,10 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
             builder.lastLogTerm(lastLogEntry.getTerm());
         }
 
-        if (getCurrentBehavior() instanceof AbstractLeader) {
-            AbstractLeader leader = (AbstractLeader)getCurrentBehavior();
+        if (getCurrentBehavior() instanceof AbstractLeader leader) {
             Collection<String> followerIds = leader.getFollowerIds();
             List<FollowerInfo> followerInfoList = new ArrayList<>(followerIds.size());
-            for (String id: followerIds) {
+            for (String id : followerIds) {
                 final FollowerLogInformation info = leader.getFollower(id);
                 followerInfoList.add(new FollowerInfo(id, info.getNextIndex(), info.getMatchIndex(),
                         info.isFollowerActive(), DurationFormatUtils.formatDurationHMS(
index 2b9217e82822a5d394cc73218eaa78933e876b8a..846ef22bb08c9cec938f02d9317f76684319188a 100644 (file)
@@ -13,7 +13,6 @@ import akka.japi.Procedure;
 import org.opendaylight.controller.cluster.DataPersistenceProvider;
 import org.opendaylight.controller.cluster.DelegatingPersistentDataProvider;
 import org.opendaylight.controller.cluster.PersistentDataProvider;
-import org.opendaylight.controller.cluster.raft.messages.Payload;
 import org.opendaylight.controller.cluster.raft.messages.PersistentPayload;
 
 /**
@@ -42,33 +41,19 @@ class RaftActorDelegatingPersistentDataProvider extends DelegatingPersistentData
     }
 
     private <T> void doPersist(final T entry, final Procedure<T> procedure, final boolean async) {
-        if (getDelegate().isRecoveryApplicable()) {
-            persistSuper(entry, procedure, async);
-        } else {
-            if (entry instanceof ReplicatedLogEntry) {
-                Payload payload = ((ReplicatedLogEntry)entry).getData();
-                if (payload instanceof PersistentPayload) {
-                    // We persist the Payload but not the ReplicatedLogEntry to avoid gaps in the journal indexes
-                    // on recovery if data persistence is later enabled.
-                    if (async) {
-                        persistentProvider.persistAsync(payload, p -> procedure.apply(entry));
-                    } else {
-                        persistentProvider.persist(payload, p -> procedure.apply(entry));
-                    }
-                } else {
-                    persistSuper(entry, procedure, async);
-                }
+        if (!getDelegate().isRecoveryApplicable() && entry instanceof ReplicatedLogEntry replicatedLogEntry
+            && replicatedLogEntry.getData() instanceof PersistentPayload payload) {
+            // We persist the Payload but not the ReplicatedLogEntry to avoid gaps in the journal indexes on recovery
+            // if data persistence is later enabled.
+            if (async) {
+                persistentProvider.persistAsync(payload, p -> procedure.apply(entry));
             } else {
-                persistSuper(entry, procedure, async);
+                persistentProvider.persist(payload, p -> procedure.apply(entry));
             }
-        }
-    }
-
-    private <T> void persistSuper(final T object, final Procedure<T> procedure, final boolean async) {
-        if (async) {
-            super.persistAsync(object, procedure);
+        } else if (async) {
+            super.persistAsync(entry, procedure);
         } else {
-            super.persist(object, procedure);
+            super.persist(entry, procedure);
         }
     }
 }
index c3d5af55cd401d2e66507d61983446a5e7e1b58b..018155f4bea56319e5e504b69b09c5980fe1f8d5 100644 (file)
@@ -122,9 +122,9 @@ public class RaftActorLeadershipTransferCohort {
     void doTransfer() {
         RaftActorBehavior behavior = raftActor.getCurrentBehavior();
         // Sanity check...
-        if (behavior instanceof Leader) {
+        if (behavior instanceof Leader leader) {
             isTransferring = true;
-            ((Leader)behavior).transferLeadership(this);
+            leader.transferLeadership(this);
         } else {
             LOG.debug("{}: No longer the leader - skipping transfer", raftActor.persistenceId());
             finish(true);
index 2eb343f6919b89bd03ebd4fea5496736780060a2..389e8dfd8ff942a090a9201fa5432b944402d9d8 100644 (file)
@@ -59,19 +59,18 @@ class RaftActorRecoverySupport {
         }
 
         boolean recoveryComplete = false;
-        if (message instanceof UpdateElectionTerm) {
-            context.getTermInformation().update(((UpdateElectionTerm) message).getCurrentTerm(),
-                    ((UpdateElectionTerm) message).getVotedFor());
-        } else if (message instanceof SnapshotOffer) {
-            onRecoveredSnapshot((SnapshotOffer) message);
-        } else if (message instanceof ReplicatedLogEntry) {
-            onRecoveredJournalLogEntry((ReplicatedLogEntry) message);
-        } else if (message instanceof ApplyJournalEntries) {
-            onRecoveredApplyLogEntries(((ApplyJournalEntries) message).getToIndex());
-        } else if (message instanceof DeleteEntries) {
-            onDeleteEntries((DeleteEntries) message);
-        } else if (message instanceof ServerConfigurationPayload) {
-            context.updatePeerIds((ServerConfigurationPayload)message);
+        if (message instanceof UpdateElectionTerm updateElectionTerm) {
+            context.getTermInformation().update(updateElectionTerm.getCurrentTerm(), updateElectionTerm.getVotedFor());
+        } else if (message instanceof SnapshotOffer snapshotOffer) {
+            onRecoveredSnapshot(snapshotOffer);
+        } else if (message instanceof ReplicatedLogEntry replicatedLogEntry) {
+            onRecoveredJournalLogEntry(replicatedLogEntry);
+        } else if (message instanceof ApplyJournalEntries applyJournalEntries) {
+            onRecoveredApplyLogEntries(applyJournalEntries.getToIndex());
+        } else if (message instanceof DeleteEntries deleteEntries) {
+            onDeleteEntries(deleteEntries);
+        } else if (message instanceof ServerConfigurationPayload serverConfigurationPayload) {
+            context.updatePeerIds(serverConfigurationPayload);
         } else if (message instanceof RecoveryCompleted) {
             recoveryComplete = true;
             onRecoveryCompletedMessage(persistentProvider);
index 004272192c393b2e9267f6175312bb59bb71fdb4..e663e36bdbe0064dc923d88c18efbea5bef01f0b 100644 (file)
@@ -64,27 +64,27 @@ class RaftActorServerConfigurationSupport {
 
     RaftActorServerConfigurationSupport(final RaftActor raftActor) {
         this.raftActor = raftActor;
-        this.raftContext = raftActor.getRaftActorContext();
+        raftContext = raftActor.getRaftActorContext();
     }
 
     boolean handleMessage(final Object message, final ActorRef sender) {
-        if (message instanceof AddServer) {
-            onAddServer((AddServer) message, sender);
+        if (message instanceof AddServer addServer) {
+            onAddServer(addServer, sender);
             return true;
-        } else if (message instanceof RemoveServer) {
-            onRemoveServer((RemoveServer) message, sender);
+        } else if (message instanceof RemoveServer removeServer) {
+            onRemoveServer(removeServer, sender);
             return true;
-        } else if (message instanceof ChangeServersVotingStatus) {
-            onChangeServersVotingStatus((ChangeServersVotingStatus) message, sender);
+        } else if (message instanceof ChangeServersVotingStatus changeServersVotingStatus) {
+            onChangeServersVotingStatus(changeServersVotingStatus, sender);
             return true;
-        } else if (message instanceof ServerOperationTimeout) {
-            currentOperationState.onServerOperationTimeout((ServerOperationTimeout) message);
+        } else if (message instanceof ServerOperationTimeout serverOperationTimeout) {
+            currentOperationState.onServerOperationTimeout(serverOperationTimeout);
             return true;
-        } else if (message instanceof UnInitializedFollowerSnapshotReply) {
-            currentOperationState.onUnInitializedFollowerSnapshotReply((UnInitializedFollowerSnapshotReply) message);
+        } else if (message instanceof UnInitializedFollowerSnapshotReply uninitFollowerSnapshotReply) {
+            currentOperationState.onUnInitializedFollowerSnapshotReply(uninitFollowerSnapshotReply);
             return true;
-        } else if (message instanceof ApplyState) {
-            return onApplyState((ApplyState) message);
+        } else if (message instanceof ApplyState applyState) {
+            return onApplyState(applyState);
         } else if (message instanceof SnapshotComplete) {
             currentOperationState.onSnapshotComplete();
             return false;
@@ -765,8 +765,7 @@ class RaftActorServerConfigurationSupport {
             }
 
             raftContext.updatePeerIds(new ServerConfigurationPayload(newServerInfoList));
-            if (raftActor.getCurrentBehavior() instanceof AbstractLeader) {
-                AbstractLeader leader = (AbstractLeader) raftActor.getCurrentBehavior();
+            if (raftActor.getCurrentBehavior() instanceof AbstractLeader leader) {
                 leader.updateMinReplicaCount();
             }
 
index bc96713dc46f31f7974ddb02a70ee50a3f1f62b7..e7344d9b4f17f74e347cf0fc339ff211243a46b5 100644 (file)
@@ -60,18 +60,18 @@ class RaftActorSnapshotMessageSupport {
     }
 
     boolean handleSnapshotMessage(final Object message, final ActorRef sender) {
-        if (message instanceof ApplySnapshot) {
-            onApplySnapshot((ApplySnapshot) message);
-        } else if (message instanceof SaveSnapshotSuccess) {
-            onSaveSnapshotSuccess((SaveSnapshotSuccess) message);
-        } else if (message instanceof SaveSnapshotFailure) {
-            onSaveSnapshotFailure((SaveSnapshotFailure) message);
-        } else if (message instanceof CaptureSnapshotReply) {
-            onCaptureSnapshotReply((CaptureSnapshotReply) message);
+        if (message instanceof ApplySnapshot applySnapshot) {
+            onApplySnapshot(applySnapshot);
+        } else if (message instanceof SaveSnapshotSuccess saveSnapshotSuccess) {
+            onSaveSnapshotSuccess(saveSnapshotSuccess);
+        } else if (message instanceof SaveSnapshotFailure saveSnapshotFailure) {
+            onSaveSnapshotFailure(saveSnapshotFailure);
+        } else if (message instanceof CaptureSnapshotReply captureSnapshotReply) {
+            onCaptureSnapshotReply(captureSnapshotReply);
         } else if (COMMIT_SNAPSHOT.equals(message)) {
             context.getSnapshotManager().commit(-1, -1);
-        } else if (message instanceof GetSnapshot) {
-            onGetSnapshot(sender, (GetSnapshot) message);
+        } else if (message instanceof GetSnapshot getSnapshot) {
+            onGetSnapshot(sender, getSnapshot);
         } else if (message instanceof SnapshotComplete) {
             log.debug("{}: SnapshotComplete received", context.getId());
         } else {
index 6bccde0d622b48ecb2a9f97cd4e41aecca3dbf6f..bdd3262e0ac0b37b515c79c7295ffde30f4dde05 100644 (file)
@@ -469,8 +469,8 @@ public abstract class AbstractLeader extends AbstractRaftActorBehavior {
         // and became the leader again,. We still want to apply this as a local modification because
         // we have resumed leadership with that log entry having been committed.
         final Payload payload = entry.getData();
-        if (payload instanceof IdentifiablePayload) {
-            return new ApplyState(null, ((IdentifiablePayload<?>) payload).getIdentifier(), entry);
+        if (payload instanceof IdentifiablePayload<?> identifiable) {
+            return new ApplyState(null, identifiable.getIdentifier(), entry);
         }
 
         return new ApplyState(null, null, entry);
@@ -511,9 +511,9 @@ public abstract class AbstractLeader extends AbstractRaftActorBehavior {
                 // start a new election due to lack of responses. This case would only occur if there isn't a majority
                 // of other nodes available that can elect the requesting candidate. Since we're transferring
                 // leadership, we should make every effort to get the requesting node elected.
-                if (rpc instanceof RequestVote && context.getRaftActorLeadershipTransferCohort() != null) {
+                if (rpc instanceof RequestVote requestVote && context.getRaftActorLeadershipTransferCohort() != null) {
                     log.debug("{}: Leadership transfer in progress - processing RequestVote", logName());
-                    super.handleMessage(sender, rpc);
+                    requestVote(sender, requestVote);
                 }
 
                 return internalSwitchBehavior(RaftState.Follower);
@@ -528,10 +528,10 @@ public abstract class AbstractLeader extends AbstractRaftActorBehavior {
             setSnapshotHolder(new SnapshotHolder(sendInstallSnapshot.getSnapshot(),
                 sendInstallSnapshot.getSnapshotBytes()));
             sendInstallSnapshot();
-        } else if (message instanceof Replicate) {
-            replicate((Replicate) message);
-        } else if (message instanceof InstallSnapshotReply) {
-            handleInstallSnapshotReply((InstallSnapshotReply) message);
+        } else if (message instanceof Replicate replicate) {
+            replicate(replicate);
+        } else if (message instanceof InstallSnapshotReply installSnapshotReply) {
+            handleInstallSnapshotReply(installSnapshotReply);
         } else if (message instanceof CheckConsensusReached) {
             possiblyUpdateCommitIndex();
         } else {
index e714fddb749ad902d9fada289d4cc3425fa6cb04..d2a73b249d1239ed51df73ab2e44e7b6539c8bb6 100644 (file)
@@ -76,20 +76,13 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
     }
 
     public static RaftActorBehavior createBehavior(final RaftActorContext context, final RaftState state) {
-        switch (state) {
-            case Candidate:
-                return new Candidate(context);
-            case Follower:
-                return new Follower(context);
-            case IsolatedLeader:
-                return new IsolatedLeader(context);
-            case Leader:
-                return new Leader(context);
-            case PreLeader:
-                return new PreLeader(context);
-            default:
-                throw new IllegalArgumentException("Unhandled state " + state);
-        }
+        return switch (state) {
+            case Candidate -> new Candidate(context);
+            case Follower -> new Follower(context);
+            case IsolatedLeader -> new IsolatedLeader(context);
+            case Leader -> new Leader(context);
+            case PreLeader -> new PreLeader(context);
+        };
     }
 
     @Override
@@ -418,14 +411,14 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
 
     @Override
     public RaftActorBehavior handleMessage(final ActorRef sender, final Object message) {
-        if (message instanceof AppendEntries) {
-            return appendEntries(sender, (AppendEntries) message);
-        } else if (message instanceof AppendEntriesReply) {
-            return handleAppendEntriesReply(sender, (AppendEntriesReply) message);
-        } else if (message instanceof RequestVote) {
-            return requestVote(sender, (RequestVote) message);
-        } else if (message instanceof RequestVoteReply) {
-            return handleRequestVoteReply(sender, (RequestVoteReply) message);
+        if (message instanceof AppendEntries appendEntries) {
+            return appendEntries(sender, appendEntries);
+        } else if (message instanceof AppendEntriesReply appendEntriesReply) {
+            return handleAppendEntriesReply(sender, appendEntriesReply);
+        } else if (message instanceof RequestVote requestVote) {
+            return requestVote(sender, requestVote);
+        } else if (message instanceof RequestVoteReply requestVoteReply) {
+            return handleRequestVoteReply(sender, requestVoteReply);
         } else {
             return null;
         }
@@ -446,12 +439,12 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
             return this;
         }
 
-        log.info("{} :- Switching from behavior {} to {}, election term: {}", logName(), this.state(),
+        log.info("{} :- Switching from behavior {} to {}, election term: {}", logName(), state(),
                 newBehavior.state(), context.getTermInformation().getCurrentTerm());
         try {
             close();
         } catch (RuntimeException e) {
-            log.error("{}: Failed to close behavior : {}", logName(), this.state(), e);
+            log.error("{}: Failed to close behavior : {}", logName(), state(), e);
         }
         return newBehavior;
     }
@@ -502,11 +495,10 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
     // Check whether we should update the term. In case of half-connected nodes, we want to ignore RequestVote
     // messages, as the candidate is not able to receive our response.
     protected boolean shouldUpdateTerm(final RaftRPC rpc) {
-        if (!(rpc instanceof RequestVote)) {
+        if (!(rpc instanceof RequestVote requestVote)) {
             return true;
         }
 
-        final RequestVote requestVote = (RequestVote) rpc;
         log.debug("{}: Found higher term in RequestVote rpc, verifying whether it's safe to update term.", logName());
         final Optional<Cluster> maybeCluster = context.getCluster();
         if (!maybeCluster.isPresent()) {
index 6e1ca82f77d80571f74e6d4b49229ed02445ea98..f5a2d085fe8ed968f49134de286e0bd6ca8bcec9 100644 (file)
@@ -18,10 +18,10 @@ import org.eclipse.jdt.annotation.NonNull;
  * @author Thomas Pantelis
  */
 public final class ServerInfo {
-    private final String id;
+    private final @NonNull String id;
     private final boolean isVoting;
 
-    public ServerInfo(@NonNull String id, boolean isVoting) {
+    public ServerInfo(final @NonNull String id, final boolean isVoting) {
         this.id = requireNonNull(id);
         this.isVoting = isVoting;
     }
@@ -44,16 +44,8 @@ public final class ServerInfo {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof ServerInfo)) {
-            return false;
-        }
-
-        final ServerInfo other = (ServerInfo) obj;
-        return isVoting == other.isVoting && id.equals(other.id);
+    public boolean equals(final Object obj) {
+        return this == obj || obj instanceof ServerInfo other && isVoting == other.isVoting && id.equals(other.id);
     }
 
     @Override
index f1c2fea4a6013cc41f1dde5008fff04170d4711a..250551a780d0a5842e409f2b59315f8d63b27191 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.cluster.raft.persisted;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import akka.actor.ExtendedActorSystem;
@@ -45,10 +44,11 @@ public class SimpleReplicatedLogEntrySerializer extends JSerializer {
     }
 
     @Override
-    public byte[] toBinary(Object obj) {
-        checkArgument(obj instanceof SimpleReplicatedLogEntry, "Unsupported object type %s", obj.getClass());
+    public byte[] toBinary(final Object obj) {
+        if (!(obj instanceof SimpleReplicatedLogEntry replicatedLogEntry)) {
+            throw new IllegalArgumentException("Unsupported object type " + obj.getClass());
+        }
 
-        SimpleReplicatedLogEntry replicatedLogEntry = (SimpleReplicatedLogEntry)obj;
         final int estimatedSerializedSize = replicatedLogEntry.serializedSize();
 
         final ByteArrayOutputStream bos = new ByteArrayOutputStream(estimatedSerializedSize);
@@ -62,7 +62,7 @@ public class SimpleReplicatedLogEntrySerializer extends JSerializer {
     }
 
     @Override
-    public Object fromBinaryJava(byte[] bytes, Class<?> manifest) {
+    public Object fromBinaryJava(final byte[] bytes, final Class<?> manifest) {
         try (ClassLoaderObjectInputStream is = new ClassLoaderObjectInputStream(system.dynamicAccess().classLoader(),
                 new ByteArrayInputStream(bytes))) {
             return is.readObject();