Browse Source

Use Map interface instead of ConcurrentHashMap class

On Android, the co-variant override of ConcurrentHashMap.keySet()
introduced in Java 8 was undone. [1] If compiled Java code calls that
co-variant override directly, one gets a NoSuchMethodError exception
at run-time on Android.

Making the code call that method via Map.keySet() side-steps this
problem.

This is similar to bug 496262, where the same problem cropped up when
compiling with Java 8 against a Java 7 target, but here we cannot use
bootclasspath. We build against Java 8, not against the Android version
of it.

Recent Android versions should have some bytecode "magic" that adds the
co-variant override in bytecode (see the commit referenced in [1]), but
on older Android version this problem may still occur. (Or perhaps the
"magic" is ineffective...) There are two pull requests on Github for
this problem, both from 2020, [2][3] while the Android commit [1] is
from March 2018. Apparently people still occasionally run into this
problem in the wild.

[1] 0e8b937ded/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java (1244)
[2] https://github.com/eclipse/jgit/pull/104
[3] https://github.com/eclipse/jgit/pull/100

Change-Id: I7c07e0cc59871cb7fe60795e22867827fa9c2458
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
tags/v5.11.0.202102031030-m2
Thomas Wolf 3 years ago
parent
commit
0f442d7083

+ 2
- 2
org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java View File

import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.security.AbstractLoginService; import org.eclipse.jetty.security.AbstractLoginService;
static class TestMappedLoginService extends AbstractLoginService { static class TestMappedLoginService extends AbstractLoginService {
private String role; private String role;


protected final ConcurrentMap<String, UserPrincipal> users = new ConcurrentHashMap<>();
protected final Map<String, UserPrincipal> users = new ConcurrentHashMap<>();


TestMappedLoginService(String role) { TestMappedLoginService(String role) {
this.role = role; this.role = role;

+ 2
- 3
org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java View File

import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.JGitInternalException;
* Available archival formats (corresponding to values for * Available archival formats (corresponding to values for
* the --format= option) * the --format= option)
*/ */
private static final ConcurrentMap<String, FormatEntry> formats =
private static final Map<String, FormatEntry> formats =
new ConcurrentHashMap<>(); new ConcurrentHashMap<>();


/** /**
* @param newValue value to be associated with the key (null to remove). * @param newValue value to be associated with the key (null to remove).
* @return true if the value was replaced * @return true if the value was replaced
*/ */
private static <K, V> boolean replace(ConcurrentMap<K, V> map,
private static <K, V> boolean replace(Map<K, V> map,
K key, V oldValue, V newValue) { K key, V oldValue, V newValue) {
if (oldValue == null && newValue == null) // Nothing to do. if (oldValue == null && newValue == null) // Nothing to do.
return true; return true;

+ 2
- 1
org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java View File

import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;


* @since 4.6 * @since 4.6
*/ */
public class FilterCommandRegistry { public class FilterCommandRegistry {
private static ConcurrentHashMap<String, FilterCommandFactory> filterCommandRegistry = new ConcurrentHashMap<>();
private static Map<String, FilterCommandFactory> filterCommandRegistry = new ConcurrentHashMap<>();


/** /**
* Register a {@link org.eclipse.jgit.attributes.FilterCommandFactory} * Register a {@link org.eclipse.jgit.attributes.FilterCommandFactory}

+ 2
- 2
org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java View File

package org.eclipse.jgit.events; package org.eclipse.jgit.events;


import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;


/** /**
* Manages a thread-safe list of {@link org.eclipse.jgit.events.RepositoryListener}s. * Manages a thread-safe list of {@link org.eclipse.jgit.events.RepositoryListener}s.
*/ */
public class ListenerList { public class ListenerList {
private final ConcurrentMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>> lists = new ConcurrentHashMap<>();
private final Map<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>> lists = new ConcurrentHashMap<>();


/** /**
* Register a {@link org.eclipse.jgit.events.WorkingTreeModifiedListener}. * Register a {@link org.eclipse.jgit.events.WorkingTreeModifiedListener}.

+ 2
- 1
org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java View File

import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
cache.configureEviction(repositoryCacheConfig); cache.configureEviction(repositoryCacheConfig);
} }


private final ConcurrentHashMap<Key, Repository> cacheMap;
private final Map<Key, Repository> cacheMap;


private final Lock[] openLocks; private final Lock[] openLocks;



+ 3
- 1
org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java View File

package org.eclipse.jgit.nls; package org.eclipse.jgit.nls;


import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;


import org.eclipse.jgit.errors.TranslationBundleLoadingException; import org.eclipse.jgit.errors.TranslationBundleLoadingException;
} }


private final Locale locale; private final Locale locale;
private final ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<>();

private final Map<Class, TranslationBundle> map = new ConcurrentHashMap<>();


private NLS(Locale locale) { private NLS(Locale locale) {
this.locale = locale; this.locale = locale;

Loading…
Cancel
Save