You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2018/06/21 20:19:49 UTC

[tika] 01/03: TIKA-2677 -- fix multithreaded updating/access to MediaTypeRegistry, via Yuriy Koval

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

tallison pushed a commit to branch branch_1x
in repository https://gitbox.apache.org/repos/asf/tika.git

commit b4cdfcfe19b008c2e9955f42caf6d52e8389a172
Author: tballison <ta...@mitre.org>
AuthorDate: Wed Jun 20 16:26:12 2018 -0400

    TIKA-2677 -- fix multithreaded updating/access to MediaTypeRegistry, via Yuriy Koval
---
 .../org/apache/tika/mime/MediaTypeRegistry.java    |  5 +++--
 .../main/java/org/apache/tika/mime/MimeTypes.java  |  5 ++---
 .../org/apache/tika/mime/MimeTypesReaderTest.java  | 22 ++++++++++++++++++++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/tika-core/src/main/java/org/apache/tika/mime/MediaTypeRegistry.java b/tika-core/src/main/java/org/apache/tika/mime/MediaTypeRegistry.java
index 813eda0..65938be 100644
--- a/tika-core/src/main/java/org/apache/tika/mime/MediaTypeRegistry.java
+++ b/tika-core/src/main/java/org/apache/tika/mime/MediaTypeRegistry.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Registry of known Internet media types.
@@ -46,7 +47,7 @@ public class MediaTypeRegistry implements Serializable {
      * as a mapping from the alias to the corresponding canonical type.
      */
     private final Map<MediaType, MediaType> registry =
-        new HashMap<MediaType, MediaType>();
+        new ConcurrentHashMap<>();
 
     /**
      * Known type inheritance relationships. The mapping is from a media type
@@ -74,7 +75,7 @@ public class MediaTypeRegistry implements Serializable {
      * @return known aliases
      */
     public SortedSet<MediaType> getAliases(MediaType type) {
-        SortedSet<MediaType> aliases = new TreeSet<MediaType>();
+        SortedSet<MediaType> aliases = new TreeSet<>();
         for (Map.Entry<MediaType, MediaType> entry : registry.entrySet()) {
             if (entry.getValue().equals(type) && !entry.getKey().equals(type)) {
                 aliases.add(entry.getKey());
diff --git a/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java b/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java
index 46b9d8f..705ad3d 100644
--- a/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java
+++ b/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.xml.namespace.QName;
 
@@ -102,8 +103,7 @@ public final class MimeTypes implements Detector, Serializable {
     private final MediaTypeRegistry registry = new MediaTypeRegistry();
 
     /** All the registered MimeTypes indexed on their canonical names */
-    private final Map<MediaType, MimeType> types =
-        new HashMap<MediaType, MimeType>();
+    private final Map<MediaType, MimeType> types = new HashMap<>();
 
     /** The patterns matcher */
     private Patterns patterns = new Patterns(registry);
@@ -425,7 +425,6 @@ public final class MimeTypes implements Detector, Serializable {
      *
      * @return the minimum length of data to provide.
      * @see #getMimeType(byte[])
-     * @see #getMimeType(String, byte[])
      */
     public int getMinLength() {
         // This needs to be reasonably large to be able to correctly detect
diff --git a/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java b/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
index 8782167..0c1f494 100644
--- a/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
+++ b/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
@@ -25,8 +25,10 @@ import static org.junit.Assert.fail;
 import java.io.ByteArrayInputStream;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Executors;
 
 import org.apache.tika.config.TikaConfig;
 import org.apache.tika.metadata.Metadata;
@@ -48,6 +50,8 @@ import org.junit.Test;
  */
 public class MimeTypesReaderTest {
 
+    static boolean stop = false;
+
     private MimeTypes mimeTypes;
     private List<Magic> magics;
 
@@ -279,4 +283,22 @@ public class MimeTypesReaderTest {
         assertEquals(name, mimeType.toString());
         assertEquals(".ditamap", mimeType.getExtension());
     }
+
+    @Test
+    public void testMultiThreaded() throws Exception {
+        MimeTypes mimeTypes = MimeTypes.getDefaultMimeTypes();
+        Executors.newSingleThreadExecutor().execute(()-> {
+            try {
+                for (int i = 0; i < 500 && !stop; i++) {
+                    mimeTypes.forName("abc"+i+"/abc");
+                }
+            } catch (MimeTypeException e ) {
+                e.printStackTrace();
+            }}
+        );
+
+        for (int i = 0; i < 500 & !stop; i++) {
+            mimeTypes.getMediaTypeRegistry().getAliases(MediaType.APPLICATION_ZIP);
+        }
+    }
 }