You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by si...@apache.org on 2019/07/21 06:20:50 UTC

[pulsar] branch master updated: Removed specialization of CopyOnWriteArrayList class (#4710)

This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new e7c8109  Removed specialization of CopyOnWriteArrayList class (#4710)
e7c8109 is described below

commit e7c81096dc0699bd6cdc0cb4756f37e9c0e6f04f
Author: Matteo Merli <mm...@apache.org>
AuthorDate: Sat Jul 20 23:20:46 2019 -0700

    Removed specialization of CopyOnWriteArrayList class (#4710)
    
    ### Motivation
    
    Switched back to use the regular `java.util.concurrent.CopyOnWriteArrayList` instead of the class extending it since we don't really have any advantage in accessing the underlying array of objects.
    
    The reflection being used to get that field is giving errors on Java 12.
---
 .../AbstractDispatcherMultipleConsumers.java       |  13 ++-
 .../AbstractDispatcherSingleActiveConsumer.java    |   6 +-
 .../apache/pulsar/broker/service/Dispatcher.java   |   3 +-
 .../nonpersistent/NonPersistentDispatcher.java     |  13 +--
 .../NonPersistentDispatcherMultipleConsumers.java  |   4 +-
 .../nonpersistent/NonPersistentSubscription.java   |   8 +-
 .../service/nonpersistent/NonPersistentTopic.java  |  10 +-
 .../PersistentDispatcherMultipleConsumers.java     |   2 +-
 .../service/persistent/PersistentSubscription.java |  14 +--
 .../broker/service/persistent/PersistentTopic.java |   9 +-
 .../apache/pulsar/utils/CopyOnWriteArrayList.java  | 124 ---------------------
 .../apache/pulsar/utils/StatsOutputStreamTest.java |  81 +-------------
 12 files changed, 40 insertions(+), 247 deletions(-)

diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherMultipleConsumers.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherMultipleConsumers.java
index 464b854..7109e2c 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherMultipleConsumers.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherMultipleConsumers.java
@@ -18,18 +18,19 @@
  */
 package org.apache.pulsar.broker.service;
 
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import com.carrotsearch.hppc.ObjectHashSet;
+import com.carrotsearch.hppc.ObjectSet;
 
 import io.netty.buffer.ByteBuf;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.pulsar.broker.service.persistent.PersistentStickyKeyDispatcherMultipleConsumers;
-import org.apache.pulsar.common.protocol.Commands;
 import org.apache.pulsar.common.api.proto.PulsarApi;
 import org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
-
-import com.carrotsearch.hppc.ObjectHashSet;
-import com.carrotsearch.hppc.ObjectSet;
+import org.apache.pulsar.common.protocol.Commands;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherSingleActiveConsumer.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherSingleActiveConsumer.java
index 48c441c..bf22238 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherSingleActiveConsumer.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractDispatcherSingleActiveConsumer.java
@@ -20,8 +20,10 @@ package org.apache.pulsar.broker.service;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -29,7 +31,6 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 import org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException;
 import org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException;
 import org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -238,7 +239,8 @@ public abstract class AbstractDispatcherSingleActiveConsumer extends AbstractBas
         return ACTIVE_CONSUMER_UPDATER.get(this);
     }
 
-    public CopyOnWriteArrayList<Consumer> getConsumers() {
+    @Override
+    public List<Consumer> getConsumers() {
         return consumers;
     }
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/Dispatcher.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/Dispatcher.java
index 3f839b17..cda9c09 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/Dispatcher.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/Dispatcher.java
@@ -27,7 +27,6 @@ import org.apache.pulsar.broker.service.persistent.DispatchRateLimiter;
 import org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType;
 import org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata;
 import org.apache.pulsar.common.policies.data.Policies;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
 
 public interface Dispatcher {
     void addConsumer(Consumer consumer) throws BrokerServiceException;
@@ -43,7 +42,7 @@ public interface Dispatcher {
 
     boolean isConsumerConnected();
 
-    CopyOnWriteArrayList<Consumer> getConsumers();
+    List<Consumer> getConsumers();
 
     boolean canUnsubscribe(Consumer consumer);
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcher.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcher.java
index 1f46854..09401c6 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcher.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcher.java
@@ -28,7 +28,6 @@ import org.apache.pulsar.broker.service.BrokerServiceException;
 import org.apache.pulsar.broker.service.Consumer;
 import org.apache.pulsar.broker.service.Dispatcher;
 import org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
 
 
 public interface NonPersistentDispatcher extends Dispatcher{
@@ -38,8 +37,8 @@ public interface NonPersistentDispatcher extends Dispatcher{
     void removeConsumer(Consumer consumer) throws BrokerServiceException ;
 
     boolean isConsumerConnected();
-    
-    CopyOnWriteArrayList<Consumer> getConsumers();
+
+    List<Consumer> getConsumers();
 
     boolean canUnsubscribe(Consumer consumer);
 
@@ -50,13 +49,13 @@ public interface NonPersistentDispatcher extends Dispatcher{
     void reset();
 
     SubType getType();
-    
+
     void sendMessages(List<Entry> entries);
-    
+
     Rate getMesssageDropRate();
-    
+
     boolean hasPermits();
-    
+
     @Override
     default void redeliverUnacknowledgedMessages(Consumer consumer) {
         // No-op
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcherMultipleConsumers.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcherMultipleConsumers.java
index b2f6d38..b12d4f2 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcherMultipleConsumers.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentDispatcherMultipleConsumers.java
@@ -20,6 +20,7 @@ package org.apache.pulsar.broker.service.nonpersistent;
 
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 
 import org.apache.bookkeeper.mledger.Entry;
@@ -34,9 +35,8 @@ import org.apache.pulsar.broker.service.RedeliveryTracker;
 import org.apache.pulsar.broker.service.RedeliveryTrackerDisabled;
 import org.apache.pulsar.broker.service.SendMessageInfo;
 import org.apache.pulsar.broker.service.Subscription;
-import org.apache.pulsar.common.protocol.Commands;
 import org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
+import org.apache.pulsar.common.protocol.Commands;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentSubscription.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentSubscription.java
index beba94b..97645ce 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentSubscription.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentSubscription.java
@@ -20,6 +20,7 @@ package org.apache.pulsar.broker.service.nonpersistent;
 
 import com.google.common.base.MoreObjects;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -41,7 +42,6 @@ import org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType;
 import org.apache.pulsar.common.naming.TopicName;
 import org.apache.pulsar.common.policies.data.ConsumerStats;
 import org.apache.pulsar.common.policies.data.NonPersistentSubscriptionStats;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -182,6 +182,8 @@ public class NonPersistentSubscription implements Subscription {
             return "Failover";
         case Shared:
             return "Shared";
+        case Key_Shared:
+            return "Key_Shared";
         }
 
         return "Null";
@@ -306,12 +308,12 @@ public class NonPersistentSubscription implements Subscription {
     }
 
     @Override
-    public CopyOnWriteArrayList<Consumer> getConsumers() {
+    public List<Consumer> getConsumers() {
         Dispatcher dispatcher = this.dispatcher;
         if (dispatcher != null) {
             return dispatcher.getConsumers();
         } else {
-            return CopyOnWriteArrayList.empty();
+            return Collections.emptyList();
         }
     }
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentTopic.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentTopic.java
index d7a3eed..60a8beb 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentTopic.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentTopic.java
@@ -678,14 +678,12 @@ public class NonPersistentTopic extends AbstractTopic implements Topic {
             // Start subscription name & consumers
             try {
                 topicStatsStream.startObject(subscriptionName);
-                Object[] consumers = subscription.getConsumers().array();
-                nsStats.consumerCount += consumers.length;
-                bundleStats.consumerCount += consumers.length;
-
                 topicStatsStream.startList("consumers");
 
-                for (Object consumerObj : consumers) {
-                    Consumer consumer = (Consumer) consumerObj;
+                for (Consumer consumer : subscription.getConsumers()) {
+                    ++nsStats.consumerCount;
+                    ++bundleStats.consumerCount;
+
                     consumer.updateRates();
 
                     ConsumerStats consumerStats = consumer.getStats();
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java
index fdb5f19..4dff4c4 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 
@@ -62,7 +63,6 @@ import org.apache.pulsar.common.policies.data.Policies;
 import org.apache.pulsar.common.util.Codec;
 import org.apache.pulsar.common.util.collections.ConcurrentSortedLongPairSet;
 import org.apache.pulsar.common.util.collections.LongPairSet;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentSubscription.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentSubscription.java
index 16651ee..d4adf45 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentSubscription.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentSubscription.java
@@ -18,13 +18,12 @@
  */
 package org.apache.pulsar.broker.service.persistent;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import com.google.common.base.MoreObjects;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -32,8 +31,6 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
 
 import org.apache.bookkeeper.mledger.AsyncCallbacks;
 import org.apache.bookkeeper.mledger.AsyncCallbacks.ClearBacklogCallback;
@@ -70,12 +67,9 @@ import org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap;
 import org.apache.pulsar.common.util.collections.ConcurrentOpenHashSet;
 import org.apache.pulsar.transaction.common.exception.TransactionConflictException;
 import org.apache.pulsar.transaction.impl.common.TxnID;
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
 public class PersistentSubscription implements Subscription {
     protected final PersistentTopic topic;
     protected final ManagedCursor cursor;
@@ -819,12 +813,12 @@ public class PersistentSubscription implements Subscription {
     }
 
     @Override
-    public CopyOnWriteArrayList<Consumer> getConsumers() {
+    public List<Consumer> getConsumers() {
         Dispatcher dispatcher = this.dispatcher;
         if (dispatcher != null) {
             return dispatcher.getConsumers();
         } else {
-            return CopyOnWriteArrayList.empty();
+            return Collections.emptyList();
         }
     }
 
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java
index f1f901c..c1faa8b 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java
@@ -1277,14 +1277,11 @@ public class PersistentTopic extends AbstractTopic implements Topic, AddEntryCal
             // Start subscription name & consumers
             try {
                 topicStatsStream.startObject(subscriptionName);
-                Object[] consumers = subscription.getConsumers().array();
-                nsStats.consumerCount += consumers.length;
-                bundleStats.consumerCount += consumers.length;
-
                 topicStatsStream.startList("consumers");
 
-                for (Object consumerObj : consumers) {
-                    Consumer consumer = (Consumer) consumerObj;
+                for (Consumer consumer : subscription.getConsumers()) {
+                    ++nsStats.consumerCount;
+                    ++bundleStats.consumerCount;
                     consumer.updateRates();
 
                     ConsumerStats consumerStats = consumer.getStats();
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/utils/CopyOnWriteArrayList.java b/pulsar-broker/src/main/java/org/apache/pulsar/utils/CopyOnWriteArrayList.java
deleted file mode 100644
index 82ff27e..0000000
--- a/pulsar-broker/src/main/java/org/apache/pulsar/utils/CopyOnWriteArrayList.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * 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.pulsar.utils;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.function.Predicate;
-import java.util.function.UnaryOperator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CopyOnWriteArrayList<T> extends java.util.concurrent.CopyOnWriteArrayList<T> {
-    private static final long serialVersionUID = 1L;
-
-    private static final Logger log = LoggerFactory.getLogger(CopyOnWriteArrayList.class);
-    private static final Method getArrayMethod;
-
-    static {
-        try {
-            getArrayMethod = java.util.concurrent.CopyOnWriteArrayList.class.getDeclaredMethod("getArray");
-            getArrayMethod.setAccessible(true);
-        } catch (Exception e) {
-            log.error("Error in getting method", e);
-            throw new RuntimeException(e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public T[] array() {
-        try {
-            return (T[]) getArrayMethod.invoke(this);
-        } catch (Exception e) {
-            log.error("Error in invoking method", e);
-            throw new RuntimeException(e);
-        }
-    }
-
-    @SuppressWarnings({ "rawtypes", "serial" })
-    public static final CopyOnWriteArrayList EMPTY_LIST = new CopyOnWriteArrayList() {
-
-        @Override
-        public Object set(int index, Object element) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean add(Object e) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void add(int index, Object element) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Object remove(int index) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean remove(Object o) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean addIfAbsent(Object e) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean removeAll(Collection c) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int addAllAbsent(Collection c) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean addAll(Collection c) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean addAll(int index, Collection c) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean removeIf(Predicate filter) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void replaceAll(UnaryOperator operator) {
-            throw new UnsupportedOperationException();
-        }
-
-    };
-
-    @SuppressWarnings("unchecked")
-    public static <T> CopyOnWriteArrayList<T> empty() {
-        return EMPTY_LIST;
-    }
-}
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/utils/StatsOutputStreamTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/utils/StatsOutputStreamTest.java
index e9ad936..a89fa1a 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/utils/StatsOutputStreamTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/utils/StatsOutputStreamTest.java
@@ -19,18 +19,15 @@
 package org.apache.pulsar.utils;
 
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 
 import java.nio.charset.Charset;
 
-import org.apache.pulsar.utils.CopyOnWriteArrayList;
-import org.apache.pulsar.utils.StatsOutputStream;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-
 public class StatsOutputStreamTest {
 
     private ByteBuf buf;
@@ -147,78 +144,6 @@ public class StatsOutputStreamTest {
         assertEquals(str(), "[{\"a\":1},{\"b\":2}]");
     }
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCopyOnWriteArrayList() {
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.add(1);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.set(0, 0);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.add(1, 1);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.remove(1);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.remove("Object");
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.addIfAbsent(1);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.removeAll(CopyOnWriteArrayList.EMPTY_LIST);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.addAllAbsent(CopyOnWriteArrayList.EMPTY_LIST);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.addAll(CopyOnWriteArrayList.EMPTY_LIST);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.removeIf(null);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-        try {
-            CopyOnWriteArrayList.EMPTY_LIST.replaceAll(null);
-            fail();
-        } catch (UnsupportedOperationException e) {
-            // Ok
-        }
-
-    }
-
     public String str() {
         String s = buf.toString(Charset.forName("utf-8"));
         reset();