Bug 1457255 - 4. Fix remaining Java warnings; r=me on CLOSED TREE
☠☠ backed out by 258fa1eb49c9 ☠ ☠
authorJim Chen <nchen@mozilla.com>
Tue, 01 May 2018 01:01:00 -0400
changeset 472516 9c42ce50a911718ea64e5d2266cf02d37e6e444f
parent 472515 524a0f9fb9788b5fc7c7ed3aefe41a981bb546f3
child 472517 5bf7bfe1db79fc344db9fa64dbae539771a8db75
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1457255
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1457255 - 4. Fix remaining Java warnings; r=me on CLOSED TREE
mobile/android/app/src/test/java/org/mozilla/gecko/TestGeckoProfile.java
mobile/android/app/src/test/java/org/mozilla/gecko/icons/TestIconRequest.java
mobile/android/app/src/test/java/org/mozilla/gecko/push/autopush/test/TestLiveAutopushClient.java
mobile/android/app/src/test/java/org/mozilla/gecko/telemetry/measurements/TestSearchCountMeasurements.java
mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
mobile/android/base/java/org/mozilla/gecko/dlc/BaseAction.java
mobile/android/base/java/org/mozilla/gecko/dlc/DownloadAction.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/ExtendedJSONObject.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/MetaGlobal.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/BookmarksSessionHelper.java
mobile/android/services/src/test/java/org/mozilla/gecko/sync/repositories/android/VisitsHelperTest.java
mobile/android/services/src/test/java/org/mozilla/gecko/sync/stage/test/TestFetchMetaGlobalStage.java
mobile/android/thirdparty/org/json/simple/JSONArray.java
mobile/android/thirdparty/org/json/simple/JSONObject.java
--- a/mobile/android/app/src/test/java/org/mozilla/gecko/TestGeckoProfile.java
+++ b/mobile/android/app/src/test/java/org/mozilla/gecko/TestGeckoProfile.java
@@ -154,38 +154,38 @@ public class TestGeckoProfile {
     public void testIsClientIdValid() {
         final String[] validClientIds = new String[] {
                 "905de1c0-0ea6-4a43-95f9-6170035f5a82",
                 "905de1c0-0ea6-4a43-95f9-6170035f5a83",
                 "57472f82-453d-4c55-b59c-d3c0e97b76a1",
                 "895745d1-f31e-46c3-880e-b4dd72963d4f",
         };
         for (final String validClientId : validClientIds) {
-            assertTrue("Client ID, " + validClientId + ", is valid", profile.isClientIdValid(validClientId));
+            assertTrue("Client ID, " + validClientId + ", is valid", GeckoProfile.isClientIdValid(validClientId));
         }
 
         final String[] invalidClientIds = new String[] {
                 null,
                 "",
                 "a",
                 "anInvalidClientId",
                 "905de1c0-0ea6-4a43-95f9-6170035f5a820", // too long (last section)
                 "905de1c0-0ea6-4a43-95f9-6170035f5a8", // too short (last section)
                 "05de1c0-0ea6-4a43-95f9-6170035f5a82", // too short (first section)
                 "905de1c0-0ea6-4a43-95f9-6170035f5a8!", // contains a symbol
         };
         for (final String invalidClientId : invalidClientIds) {
-            assertFalse("Client ID, " + invalidClientId + ", is invalid", profile.isClientIdValid(invalidClientId));
+            assertFalse("Client ID, " + invalidClientId + ", is invalid", GeckoProfile.isClientIdValid(invalidClientId));
         }
 
         // We generate client IDs using UUID - better make sure they're valid.
         for (int i = 0; i < 30; ++i) {
             final String generatedClientId = UUID.randomUUID().toString();
             assertTrue("Generated client ID from UUID, " + generatedClientId + ", is valid",
-                    profile.isClientIdValid(generatedClientId));
+                    GeckoProfile.isClientIdValid(generatedClientId));
         }
     }
 
     @Test
     public void testGetProfileCreationDateFromTimesFile() throws Exception {
         final long expectedDate = System.currentTimeMillis();
         final JSONObject expectedObj = new JSONObject();
         expectedObj.put(PROFILE_CREATION_DATE_JSON_ATTR, expectedDate);
--- a/mobile/android/app/src/test/java/org/mozilla/gecko/icons/TestIconRequest.java
+++ b/mobile/android/app/src/test/java/org/mozilla/gecko/icons/TestIconRequest.java
@@ -64,17 +64,19 @@ public class TestIconRequest {
      * If removing an icon from the internal set failed then we want to throw an exception.
      */
     @Test(expected = IllegalStateException.class)
     public void testMoveToNextIconThrowsException() {
         final IconRequest request = Icons.with(RuntimeEnvironment.application)
                 .pageUrl(TEST_PAGE_URL)
                 .build();
 
+        @SuppressWarnings("unchecked")
         //noinspection unchecked - Creating a mock of a generic type
-        request.icons = (TreeSet<IconDescriptor>) mock(TreeSet.class);
+        final TreeSet<IconDescriptor> icons = (TreeSet<IconDescriptor>) mock(TreeSet.class);
+        request.icons = icons;
 
         //noinspection SuspiciousMethodCalls
         doReturn(false).when(request.icons).remove(anyObject());
 
         request.moveToNextIcon();
     }
 }
--- a/mobile/android/app/src/test/java/org/mozilla/gecko/push/autopush/test/TestLiveAutopushClient.java
+++ b/mobile/android/app/src/test/java/org/mozilla/gecko/push/autopush/test/TestLiveAutopushClient.java
@@ -67,104 +67,115 @@ public class TestLiveAutopushClient {
         final ArgumentCaptor<AutopushClientException> failure = ArgumentCaptor.forClass(AutopushClientException.class);
         verify(delegate).handleFailure(failure.capture());
 
         return failure.getValue();
     }
 
     @Test
     public void testUserAgent() throws Exception {
+        @SuppressWarnings("unchecked")
         final RequestDelegate<RegisterUserAgentResponse> registerDelegate = mock(RequestDelegate.class);
         client.registerUserAgent(Utils.generateGuid(), registerDelegate);
 
         final RegisterUserAgentResponse registerResponse = assertSuccess(registerDelegate, RegisterUserAgentResponse.class);
         Assert.assertNotNull(registerResponse);
         Assert.assertNotNull(registerResponse.uaid);
         Assert.assertNotNull(registerResponse.secret);
 
         // Reregistering with a new GUID should succeed.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> reregisterDelegate = mock(RequestDelegate.class);
         client.reregisterUserAgent(registerResponse.uaid, registerResponse.secret, Utils.generateGuid(), reregisterDelegate);
 
         Assert.assertNull(assertSuccess(reregisterDelegate, Void.class));
 
         // Unregistering should succeed.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> unregisterDelegate = mock(RequestDelegate.class);
         client.unregisterUserAgent(registerResponse.uaid, registerResponse.secret, unregisterDelegate);
 
         Assert.assertNull(assertSuccess(unregisterDelegate, Void.class));
 
         // Trying to unregister a second time should give a 404.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> reunregisterDelegate = mock(RequestDelegate.class);
         client.unregisterUserAgent(registerResponse.uaid, registerResponse.secret, reunregisterDelegate);
 
         final AutopushClientException failureException = assertFailure(reunregisterDelegate, Void.class);
         Assert.assertThat(failureException, instanceOf(AutopushClientException.AutopushClientRemoteException.class));
         Assert.assertTrue(((AutopushClientException.AutopushClientRemoteException) failureException).isGone());
     }
 
     @Test
     public void testChannel() throws Exception {
+        @SuppressWarnings("unchecked")
         final RequestDelegate<RegisterUserAgentResponse> registerDelegate = mock(RequestDelegate.class);
         client.registerUserAgent(Utils.generateGuid(), registerDelegate);
 
         final RegisterUserAgentResponse registerResponse = assertSuccess(registerDelegate, RegisterUserAgentResponse.class);
         Assert.assertNotNull(registerResponse);
         Assert.assertNotNull(registerResponse.uaid);
         Assert.assertNotNull(registerResponse.secret);
 
         // We should be able to subscribe to a channel.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<SubscribeChannelResponse> subscribeDelegate = mock(RequestDelegate.class);
         client.subscribeChannel(registerResponse.uaid, registerResponse.secret, null, subscribeDelegate);
 
         final SubscribeChannelResponse subscribeResponse = assertSuccess(subscribeDelegate, SubscribeChannelResponse.class);
         Assert.assertNotNull(subscribeResponse);
         Assert.assertNotNull(subscribeResponse.channelID);
         Assert.assertNotNull(subscribeResponse.endpoint);
         Assert.assertThat(subscribeResponse.endpoint, startsWith(FxAccountUtils.getAudienceForURL(serverURL)));
         Assert.assertThat(subscribeResponse.endpoint, containsString("/v1/"));
 
         // And we should be able to unsubscribe.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> unsubscribeDelegate = mock(RequestDelegate.class);
         client.unsubscribeChannel(registerResponse.uaid, registerResponse.secret, subscribeResponse.channelID, unsubscribeDelegate);
 
         Assert.assertNull(assertSuccess(unsubscribeDelegate, Void.class));
 
         // We should be able to create a restricted subscription by specifying
         // an ECDSA public key using the P-256 curve.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<SubscribeChannelResponse> subscribeWithKeyDelegate = mock(RequestDelegate.class);
         final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA");
         keyPairGenerator.initialize(256);
         final KeyPair keyPair = keyPairGenerator.generateKeyPair();
         final PublicKey publicKey = keyPair.getPublic();
         String appServerKey = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
         client.subscribeChannel(registerResponse.uaid, registerResponse.secret, appServerKey, subscribeWithKeyDelegate);
 
         final SubscribeChannelResponse subscribeWithKeyResponse = assertSuccess(subscribeWithKeyDelegate, SubscribeChannelResponse.class);
         Assert.assertNotNull(subscribeWithKeyResponse);
         Assert.assertNotNull(subscribeWithKeyResponse.channelID);
         Assert.assertNotNull(subscribeWithKeyResponse.endpoint);
         Assert.assertThat(subscribeWithKeyResponse.endpoint, startsWith(FxAccountUtils.getAudienceForURL(serverURL)));
         Assert.assertThat(subscribeWithKeyResponse.endpoint, containsString("/v2/"));
 
         // And we should be able to drop the restricted subscription.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> unsubscribeWithKeyDelegate = mock(RequestDelegate.class);
         client.unsubscribeChannel(registerResponse.uaid, registerResponse.secret, subscribeWithKeyResponse.channelID, unsubscribeWithKeyDelegate);
 
         Assert.assertNull(assertSuccess(unsubscribeWithKeyDelegate, Void.class));
 
         // Trying to unsubscribe a second time should give a 410.
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> reunsubscribeDelegate = mock(RequestDelegate.class);
         client.unsubscribeChannel(registerResponse.uaid, registerResponse.secret, subscribeResponse.channelID, reunsubscribeDelegate);
 
         final AutopushClientException reunsubscribeFailureException = assertFailure(reunsubscribeDelegate, Void.class);
         Assert.assertThat(reunsubscribeFailureException, instanceOf(AutopushClientException.AutopushClientRemoteException.class));
         Assert.assertTrue(((AutopushClientException.AutopushClientRemoteException) reunsubscribeFailureException).isGone());
 
         // Trying to unsubscribe from a non-existent channel should give a 404.  Right now it gives a 401!
+        @SuppressWarnings("unchecked")
         final RequestDelegate<Void> badUnsubscribeDelegate = mock(RequestDelegate.class);
         client.unsubscribeChannel(registerResponse.uaid + "BAD", registerResponse.secret, subscribeResponse.channelID, badUnsubscribeDelegate);
 
         final AutopushClientException badUnsubscribeFailureException = assertFailure(badUnsubscribeDelegate, Void.class);
         Assert.assertThat(badUnsubscribeFailureException, instanceOf(AutopushClientException.AutopushClientRemoteException.class));
         Assert.assertTrue(((AutopushClientException.AutopushClientRemoteException) badUnsubscribeFailureException).isInvalidAuthentication());
     }
 }
--- a/mobile/android/app/src/test/java/org/mozilla/gecko/telemetry/measurements/TestSearchCountMeasurements.java
+++ b/mobile/android/app/src/test/java/org/mozilla/gecko/telemetry/measurements/TestSearchCountMeasurements.java
@@ -140,22 +140,22 @@ public class TestSearchCountMeasurements
             editor.putInt(SearchCountMeasurements.getEngineSearchCountKey(key), expected.get(key));
         }
         editor.apply();
         assertFalse("Shared prefs is not empty after test data inserted", sharedPrefs.getAll().isEmpty());
 
         final ExtendedJSONObject actual = SearchCountMeasurements.getAndZeroSearch(sharedPrefs);
         assertEquals("Returned JSON contains number of items inserted", expected.size(), actual.size());
         for (final String key : expected.keySet()) {
-            assertEquals("Returned JSON contains inserted value", expected.get(key), (Integer) actual.getIntegerSafely(key));
+            assertEquals("Returned JSON contains inserted value", expected.get(key), actual.getIntegerSafely(key));
         }
     }
 
     @Test
     public void testGetAndZeroSearchNoData() throws Exception {
         final ExtendedJSONObject actual = SearchCountMeasurements.getAndZeroSearch(sharedPrefs);
         assertEquals("Returned json is empty", 0, actual.size());
     }
 
     private String getEngineSearchCountKey(final String engineWhereStr) {
         return SearchCountMeasurements.getEngineSearchCountKey(engineWhereStr);
     }
-}
\ No newline at end of file
+}
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
@@ -212,17 +212,17 @@ public class ActivityStreamTelemetry {
                     case BrowserContract.TopSites.TYPE_SUGGESTED:
                         this.set(Contract.SOURCE_SUBTYPE, Contract.SUBTYPE_SUGGESTED);
                         break;
                     case BrowserContract.TopSites.TYPE_TOP:
                         this.set(Contract.SOURCE_SUBTYPE, Contract.SUBTYPE_TOP);
                         break;
                     // While we also have a "blank" type, it is not used by Activity Stream.
                     case BrowserContract.TopSites.TYPE_BLANK:
-                        throw new IllegalStateException("Unknown top site type :" + topSite.getType());
+                        throw new IllegalStateException("Unknown top site type :" + String.valueOf(topSite.getType()));
                 }
 
                 return this;
             }
 
             public String build() {
                 return data.toString();
             }
--- a/mobile/android/base/java/org/mozilla/gecko/dlc/BaseAction.java
+++ b/mobile/android/base/java/org/mozilla/gecko/dlc/BaseAction.java
@@ -96,17 +96,17 @@ public abstract class BaseAction {
     protected File getDestinationFile(Context context, DownloadContent content)
             throws UnrecoverableDownloadContentException, RecoverableDownloadContentException {
         File destinationDirectory;
         if (content.isFont()) {
             destinationDirectory = new File(context.getApplicationInfo().dataDir, "fonts");
         } else if (content.isHyphenationDictionary()) {
             destinationDirectory = new File(context.getApplicationInfo().dataDir, "hyphenation");
         } else {
-            throw new UnrecoverableDownloadContentException("Can't determine destination for kind: " + content.getKind());
+            throw new UnrecoverableDownloadContentException("Can't determine destination for kind: " + content.getKind().toString());
         }
 
         if (!destinationDirectory.exists() && !destinationDirectory.mkdirs()) {
             throw new RecoverableDownloadContentException(RecoverableDownloadContentException.DISK_IO,
                     "Destination directory does not exist and cannot be created");
         }
 
         return new File(destinationDirectory, content.getFilename());
--- a/mobile/android/base/java/org/mozilla/gecko/dlc/DownloadAction.java
+++ b/mobile/android/base/java/org/mozilla/gecko/dlc/DownloadAction.java
@@ -102,17 +102,17 @@ public class DownloadAction extends Base
                 if (!verify(temporaryFile, content.getDownloadChecksum())) {
                     Log.w(LOGTAG, "Wrong checksum after download, content=" + content.getId());
                     temporaryFile.delete();
                     DownloadContentTelemetry.eventDownloadFailure(content, DownloadContentTelemetry.ERROR_CHECKSUM);
                     continue;
                 }
 
                 if (!content.isAssetArchive()) {
-                    Log.e(LOGTAG, "Downloaded content is not of type 'asset-archive': " + content.getType());
+                    Log.e(LOGTAG, "Downloaded content is not of type 'asset-archive': " + content.getType().toString());
                     temporaryFile.delete();
                     DownloadContentTelemetry.eventDownloadFailure(content, DownloadContentTelemetry.ERROR_LOGIC);
                     continue;
                 }
 
                 extract(temporaryFile, destinationFile, content.getChecksum());
 
                 catalog.markAsDownloaded(content);
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/ExtendedJSONObject.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/ExtendedJSONObject.java
@@ -266,18 +266,17 @@ public class ExtendedJSONObject implemen
   }
 
   @Override
   public String toString() {
     return this.object.toString();
   }
 
   protected void putRaw(String key, Object value) {
-    @SuppressWarnings("unchecked")
-    Map<Object, Object> map = this.object;
+    Map<String, Object> map = this.object;
     map.put(key, value);
   }
 
   public void put(String key, String value) {
     this.putRaw(key, value);
   }
 
   public void put(String key, boolean value) {
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/MetaGlobal.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/MetaGlobal.java
@@ -255,17 +255,17 @@ public class MetaGlobal {
     return new HashSet<String>(engines.keySet());
   }
 
   @SuppressWarnings("unchecked")
   public Set<String> getDeclinedEngineNames() {
     if (declined == null) {
       return null;
     }
-    return new HashSet<String>(declined);
+    return new HashSet<String>((Collection<String>) (Collection) declined);
   }
 
   /**
    * Returns if the server settings and local settings match.
    * Throws a specific MetaGlobalException if that's not the case.
    */
   public void verifyEngineSettings(String engineName, EngineSettings engineSettings)
   throws MetaGlobalException {
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/BookmarksSessionHelper.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/BookmarksSessionHelper.java
@@ -662,17 +662,18 @@ import java.util.concurrent.ConcurrentHa
                     Logger.debug(LOG_TAG, "Untracking and bumping " + guid + "(" + folderID + ")");
                     dbAccessor.bumpModified(folderID, RepositorySession.now());
                     session.untrackGUID(guid);
                 }
 
                 // If the arrays are different, or they're the same but not flushed to disk,
                 // write them out now.
                 if (!sameArrays || !clean) {
-                    dbAccessor.updatePositions(new ArrayList<>(onServer));
+                    final ArrayList<String> list = (ArrayList<String>) (ArrayList) onServer;
+                    dbAccessor.updatePositions(new ArrayList<>(list));
                 }
             } catch (Exception e) {
                 Logger.warn(LOG_TAG, "Error repositioning children for " + guid, e);
             }
         }
     }
 
     private void flushQueues(RepositorySessionStoreDelegate delegate) {
@@ -1097,17 +1098,18 @@ import java.util.concurrent.ConcurrentHa
 
             if (!persist) {
                 Logger.debug(LOG_TAG, "Returned array does not match database, and not persisting.");
                 return false;
             }
 
             Logger.debug(LOG_TAG, "Generating child array required moving records. Updating DB.");
             final long time = RepositorySession.now();
-            if (0 < dbAccessor.updatePositions(childArray)) {
+            final ArrayList<String> cArray = (ArrayList<String>) (ArrayList) childArray;
+            if (0 < dbAccessor.updatePositions(cArray)) {
                 Logger.debug(LOG_TAG, "Bumping parent time to " + time + ".");
                 dbAccessor.bumpModified(folderID, time);
             }
             return true;
         } finally {
             children.close();
         }
     }
--- a/mobile/android/services/src/test/java/org/mozilla/gecko/sync/repositories/android/VisitsHelperTest.java
+++ b/mobile/android/services/src/test/java/org/mozilla/gecko/sync/repositories/android/VisitsHelperTest.java
@@ -133,9 +133,9 @@ public class VisitsHelperTest {
             VisitsHelper.getVisitContentValues("testGUID", visit4, false);
             assertTrue("Must check that visit type and date keys are present", false);
         } catch (IllegalArgumentException e) {}
     }
 
     private Uri testUri(Uri baseUri) {
         return baseUri.buildUpon().appendQueryParameter(BrowserContract.PARAM_IS_TEST, "1").build();
     }
-}
\ No newline at end of file
+}
--- a/mobile/android/services/src/test/java/org/mozilla/gecko/sync/stage/test/TestFetchMetaGlobalStage.java
+++ b/mobile/android/services/src/test/java/org/mozilla/gecko/sync/stage/test/TestFetchMetaGlobalStage.java
@@ -35,16 +35,17 @@ import org.mozilla.gecko.sync.net.AuthHe
 import org.mozilla.gecko.sync.stage.FetchMetaGlobalStage;
 import org.mozilla.gecko.sync.stage.GlobalSyncStage.Stage;
 import org.robolectric.RobolectricTestRunner;
 import org.simpleframework.http.Request;
 import org.simpleframework.http.Response;
 
 import java.io.IOException;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -295,17 +296,17 @@ public class TestFetchMetaGlobalStage {
     // Set declined engines in the server object.
     final JSONArray testingDeclinedEngines = makeTestDeclinedArray();
     mg.setDeclinedEngineNames(testingDeclinedEngines);
 
     MockServer server = new MockServer(200, mg.asCryptoRecord().toJSONString());
     doSession(server);
 
     // Declined engines propagate from the server meta/global, and are NOT merged.
-    final Set<String> expected = new HashSet<String>(testingDeclinedEngines);
+    final Set<String> expected = new HashSet<String>((ArrayList) testingDeclinedEngines);
     // expected.add("baznoo");   // Not until we merge. Local is lost.
 
     final Set<String> newDeclined = session.config.metaGlobal.getDeclinedEngineNames();
     assertEquals(expected, newDeclined);
   }
 
   @Test
   public void testFetchMissing() throws Exception {
--- a/mobile/android/thirdparty/org/json/simple/JSONArray.java
+++ b/mobile/android/thirdparty/org/json/simple/JSONArray.java
@@ -11,17 +11,17 @@ import java.util.Iterator;
 import java.util.List;
 
 
 /**
  * A JSON array. JSONObject supports java.util.List interface.
  * 
  * @author FangYidong<fangyidong@yahoo.com.cn>
  */
-public class JSONArray extends ArrayList implements List, JSONAware, JSONStreamAware {
+public class JSONArray extends ArrayList<Object> implements List<Object>, JSONAware, JSONStreamAware {
 	private static final long serialVersionUID = 3957988303675231981L;
 
     /**
      * Encode a list into JSON text and write it to out. 
      * If this list is also a JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific behaviours will be ignored at this top level.
      * 
      * @see org.json.simple.JSONValue#writeJSONString(Object, Writer)
      * 
--- a/mobile/android/thirdparty/org/json/simple/JSONObject.java
+++ b/mobile/android/thirdparty/org/json/simple/JSONObject.java
@@ -10,17 +10,17 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
 /**
  * A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface.
  * 
  * @author FangYidong<fangyidong@yahoo.com.cn>
  */
-public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware{
+public class JSONObject extends HashMap<String, Object> implements Map<String, Object>, JSONAware, JSONStreamAware{
 	private static final long serialVersionUID = -503443796854799292L;
 
     /**
      * Encode a map into JSON text and write it to out.
      * If this map is also a JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific behaviours will be ignored at this top level.
      * 
      * @see org.json.simple.JSONValue#writeJSONString(Object, Writer)
      *