diff --git a/CHANGES.txt b/CHANGES.txt index 969b959e01..6761949457 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,6 @@ 5.1 Merged from 5.0: + * Prevent InaccessibleObjectException when the Leak Detector is traversing objects (CASSANDRA-18708) * Remove legacy command line options from cassandra-stress (CASSANDRA-18529) * Remove commitlog_sync_batch_window_in_ms (CASSANDRA-17161) * Upgrade JMH from 1.21 to 1.36 (CASSANDRA-18696) diff --git a/src/java/org/apache/cassandra/exceptions/UnaccessibleFieldException.java b/src/java/org/apache/cassandra/exceptions/UnaccessibleFieldException.java new file mode 100644 index 0000000000..d68be42487 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/UnaccessibleFieldException.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cassandra.exceptions; + +public class UnaccessibleFieldException extends RuntimeException +{ + private static final long serialVersionUID = 7340063332562337064L; + + public UnaccessibleFieldException(String message) + { + super(message); + } + + public UnaccessibleFieldException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/src/java/org/apache/cassandra/utils/concurrent/Ref.java b/src/java/org/apache/cassandra/utils/concurrent/Ref.java index 706a982f59..e268f5fd73 100644 --- a/src/java/org/apache/cassandra/utils/concurrent/Ref.java +++ b/src/java/org/apache/cassandra/utils/concurrent/Ref.java @@ -31,6 +31,8 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import org.apache.cassandra.exceptions.UnaccessibleFieldException; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,6 +51,7 @@ import org.apache.cassandra.utils.ExecutorUtils; import org.apache.cassandra.utils.NoSpamLogger; import org.apache.cassandra.utils.Pair; import org.apache.cassandra.utils.Shared; +import sun.misc.Unsafe; import sun.nio.ch.DirectBuffer; import org.cliffc.high_scale_lib.NonBlockingHashMap; @@ -73,10 +76,10 @@ import static org.apache.cassandra.utils.Throwables.merge; * - encapsulates a Ref, we'll call selfRef, to which it proxies all calls to RefCounted behaviours * - users must ensure no references to the selfRef leak, or are retained outside of a method scope. * (to ensure the selfRef is collected with the object, so that leaks may be detected and corrected) - * + *
* This class' functionality is achieved by what may look at first glance like a complex web of references, * but boils down to: - * + *
* {@code * Target --> selfRef --> [Ref.State] <--> Ref.GlobalState --> Tidy * ^ @@ -86,10 +89,10 @@ import static org.apache.cassandra.utils.Throwables.merge; * Global ------------------------------------- * } * So that, if Target is collected, Impl is collected and, hence, so is selfRef. - * + *
* Once ref or selfRef are collected, the paired Ref.State's release method is called, which if it had * not already been called will update Ref.GlobalState and log an error. - * + *
* Once the Ref.GlobalState has been completely released, the Tidy method is called and it removes the global reference
* to itself so it may also be collected.
*/
@@ -400,7 +403,7 @@ public final class Ref