New upstream version 2.8.4
Emmanuel Bourg
5 years ago
0 | 0 | Change Log |
1 | 1 | ========== |
2 | ||
3 | ## Version 2.8.3 | |
4 | _2018-04-27_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.2...gson-parent-2.8.3) | |
5 | * Added a new API, `GsonBuilder.newBuilder()` that clones the current builder | |
6 | * Preserving DateFormatter behavior on JDK 9 | |
7 | * Numerous other bugfixes | |
2 | 8 | |
3 | 9 | ## Version 2.8.2 |
4 | 10 | _2017-09-19_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.1...gson-parent-2.8.2) |
19 | 19 | * To use Gson in Android |
20 | 20 | ```gradle |
21 | 21 | dependencies { |
22 | compile 'com.google.code.gson:gson:2.8.2' | |
22 | compile 'com.google.code.gson:gson:2.8.3' | |
23 | 23 | } |
24 | 24 | ``` |
25 | 25 | |
29 | 29 | <dependency> |
30 | 30 | <groupId>com.google.code.gson</groupId> |
31 | 31 | <artifactId>gson</artifactId> |
32 | <version>2.8.2</version> | |
32 | <version>2.8.3</version> | |
33 | 33 | </dependency> |
34 | 34 | ``` |
35 | 35 |
0 | #Gson Release Process | |
0 | # Gson Release Process | |
1 | 1 | |
2 | 2 | The following is a step-by-step procedure for releasing a new version of Google-Gson. |
3 | 3 | |
9 | 9 | 1. Run `mvn release:clean` |
10 | 10 | 1. Do a dry run: `mvn release:prepare -DdryRun=true` |
11 | 11 | 1. Start the release: `mvn release:prepare` |
12 | * Answer questions: usually the defaults are fine. | |
13 | * This will do a full build, change version from `-SNAPSHOT` to the released version, commit and create the tags. It will then change the version to `-SNAPSHOT` for the next release. | |
12 | * Answer questions: usually the defaults are fine. | |
13 | * This will do a full build, change version from `-SNAPSHOT` to the released version, commit and create the tags. It will then change the version to `-SNAPSHOT` for the next release. | |
14 | 14 | 1. Ensure you have defined `sonatype-nexus-staging` in your Maven `settings.xml` and run: |
15 | 15 | |
16 | 16 | ```bash |
19 | 19 | |
20 | 20 | 1. [Log in to Nexus repository manager](https://oss.sonatype.org/index.html#welcome) at Sonatype and close the staging repository for Gson. If you run into an error regarding missing signatures, you need to manually upload the artifacts using `mvn gpg:sign-and-deploy-file` for Gson binary, source and Javadoc jars. |
21 | 21 | |
22 | ```bash | |
23 | cp -r ~/.m2/repository/com/google/code/gson/gson/1.7.2 /tmp | |
24 | cd /tmp/1.7.2 | |
22 | ```bash | |
23 | cp -r ~/.m2/repository/com/google/code/gson/gson/1.7.2 /tmp | |
24 | cd /tmp/1.7.2 | |
25 | 25 | |
26 | mvn gpg:sign-and-deploy-file \ | |
26 | mvn gpg:sign-and-deploy-file \ | |
27 | 27 | -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \ |
28 | 28 | -DrepositoryId=sonatype-nexus-staging \ |
29 | 29 | -DpomFile=gson-1.7.2.pom \ |
30 | 30 | -Dfile=gson-1.7.2-javadoc.jar \ |
31 | 31 | -Dclassifier=javadoc |
32 | 32 | |
33 | mvn gpg:sign-and-deploy-file \ | |
33 | mvn gpg:sign-and-deploy-file \ | |
34 | 34 | -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \ |
35 | 35 | -DrepositoryId=sonatype-nexus-staging \ |
36 | 36 | -DpomFile=gson-1.7.2.pom \ |
37 | 37 | -Dfile=gson-1.7.2-sources.jar \ |
38 | 38 | -Dclassifier=sources |
39 | 39 | |
40 | mvn gpg:sign-and-deploy-file \ | |
40 | mvn gpg:sign-and-deploy-file \ | |
41 | 41 | -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \ |
42 | 42 | -DrepositoryId=sonatype-nexus-staging \ |
43 | 43 | -DpomFile=gson-1.7.2.pom \ |
44 | 44 | -Dfile=gson-1.7.2.jar |
45 | ``` | |
45 | ``` | |
46 | 46 | |
47 | 47 | 1. Close the Gson repository. Download and sanity check all downloads. Do not skip this step! Once you release the staging repository, there is no going back. It will get synced with Maven central and you will not be able to update or delete anything. Your only recourse will be to release a new version of Gson and hope that no one uses the old one. |
48 | 48 | 1. Release the staging repository for Gson. Gson will now get synced to Maven central with-in the next hour. For issues consult [Sonatype Guide](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8.ReleaseIt). |
57 | 57 | This section was borrowed heavily from [Doclava release process](http://code.google.com/p/doclava/wiki/ProcessRelease). |
58 | 58 | |
59 | 59 | 1. Install/Configure GPG following this [guide](http://www.sonatype.com/people/2010/01/how-to-generate-pgp-signatures-with-maven/). |
60 | 2. [Create encrypted passwords](http://maven.apache.org/guides/mini/guide-encryption.html). | |
61 | 3. Create `~/.m2/settings.xml` similar to as described in [Doclava release process](https://code.google.com/p/doclava/wiki/ProcessRelease). | |
62 | 4. Now for deploying a snapshot repository, use `mvn deploy`. | |
60 | 1. [Create encrypted passwords](http://maven.apache.org/guides/mini/guide-encryption.html). | |
61 | 1. Create `~/.m2/settings.xml` similar to as described in [Doclava release process](https://code.google.com/p/doclava/wiki/ProcessRelease). | |
62 | 1. Now for deploying a snapshot repository, use `mvn deploy`. | |
63 | 63 | |
64 | 64 | ## Getting Maven Publishing Privileges |
65 | 65 | |
66 | 66 | Based on [Gson group thread](https://groups.google.com/d/topic/google-gson/DHWJHVFpIBg/discussion): |
67 | 67 | |
68 | 68 | 1. [Sign up for a Sonatype account](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide) following instructions under (2) on that page |
69 | 2. Ask one of the existing members of the repository to create a JIRA ticket (Step 3 of above document) to add you to the publisher list. | |
69 | 1. Ask one of the existing members of the repository to create a JIRA ticket (Step 3 of above document) to add you to the publisher list. | |
70 | 70 | |
71 | 71 | ## Running Benchmarks or Tests on Android |
72 | 72 |
73 | 73 | ## <a name="TOC-Gson-With-Gradle"></a>Using Gson with Gradle/Android |
74 | 74 | ``` |
75 | 75 | dependencies { |
76 | compile 'com.google.code.gson:gson:2.8.2' | |
76 | compile 'com.google.code.gson:gson:2.8.3' | |
77 | 77 | } |
78 | 78 | ``` |
79 | 79 | ## <a name="TOC-Gson-With-Maven"></a>Using Gson with Maven |
85 | 85 | <dependency> |
86 | 86 | <groupId>com.google.code.gson</groupId> |
87 | 87 | <artifactId>gson</artifactId> |
88 | <version>2.8.2</version> | |
88 | <version>2.8.3</version> | |
89 | 89 | <scope>compile</scope> |
90 | 90 | </dependency> |
91 | 91 | </dependencies> |
0 | buildscript { | |
1 | repositories { | |
2 | mavenCentral() | |
3 | } | |
4 | } | |
5 | ||
6 | allprojects { | |
7 | repositories { | |
8 | mavenCentral() | |
9 | } | |
10 | } | |
11 |
0 | #Fri Apr 27 17:41:01 PDT 2018 | |
1 | distributionBase=GRADLE_USER_HOME | |
2 | distributionPath=wrapper/dists | |
3 | zipStoreBase=GRADLE_USER_HOME | |
4 | zipStorePath=wrapper/dists | |
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip |
0 | apply plugin: 'java' | |
1 | apply plugin: 'maven' | |
2 | ||
3 | group = 'com.google.code.gson' | |
4 | version = '2.8.4-SNAPSHOT' | |
5 | ||
6 | sourceCompatibility = 1.6 | |
7 | targetCompatibility = 1.6 | |
8 | ||
9 | sourceSets.main.java.exclude("**/module-info.java") | |
10 | dependencies { | |
11 | testCompile "junit:junit:4.12" | |
12 | } |
3 | 3 | <parent> |
4 | 4 | <groupId>com.google.code.gson</groupId> |
5 | 5 | <artifactId>gson-parent</artifactId> |
6 | <version>2.8.3</version> | |
6 | <version>2.8.4</version> | |
7 | 7 | </parent> |
8 | 8 | |
9 | 9 | <artifactId>gson</artifactId> |
113 | 113 | @Override public String translateName(Field f) { |
114 | 114 | return separateCamelCase(f.getName(), "-").toLowerCase(Locale.ENGLISH); |
115 | 115 | } |
116 | }, | |
117 | ||
118 | /** | |
119 | * Using this naming policy with Gson will modify the Java Field name from its camel cased | |
120 | * form to a lower case field name where each word is separated by a dot (.). | |
121 | * | |
122 | * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p> | |
123 | * <ul> | |
124 | * <li>someFieldName ---> some.field.name</li> | |
125 | * <li>_someFieldName ---> _some.field.name</li> | |
126 | * <li>aStringField ---> a.string.field</li> | |
127 | * <li>aURL ---> a.u.r.l</li> | |
128 | * </ul> | |
129 | * Using dots in JavaScript is not recommended since dot is also used for a member sign in | |
130 | * expressions. This requires that a field named with dots is always accessed as a quoted | |
131 | * property like {@code myobject['my.field']}. Accessing it as an object field | |
132 | * {@code myobject.my.field} will result in an unintended javascript expression. | |
133 | * @since 2.8 | |
134 | */ | |
135 | LOWER_CASE_WITH_DOTS() { | |
136 | @Override public String translateName(Field f) { | |
137 | return separateCamelCase(f.getName(), ".").toLowerCase(Locale.ENGLISH); | |
138 | } | |
116 | 139 | }; |
117 | 140 | |
118 | 141 | /** |
24 | 24 | */ |
25 | 25 | final class PreJava9ReflectionAccessor extends ReflectionAccessor { |
26 | 26 | |
27 | /** | |
28 | * {@inheritDoc} | |
29 | */ | |
27 | /** {@inheritDoc} */ | |
30 | 28 | @Override |
31 | 29 | public void makeAccessible(AccessibleObject ao) { |
32 | 30 | ao.setAccessible(true); |
33 | 31 | } |
34 | ||
35 | 32 | } |
14 | 14 | */ |
15 | 15 | package com.google.gson.internal.reflect; |
16 | 16 | |
17 | import sun.misc.Unsafe; | |
18 | ||
19 | 17 | import java.lang.reflect.AccessibleObject; |
20 | 18 | import java.lang.reflect.Field; |
19 | import java.lang.reflect.Method; | |
20 | ||
21 | import com.google.gson.JsonIOException; | |
21 | 22 | |
22 | 23 | /** |
23 | 24 | * An implementation of {@link ReflectionAccessor} based on {@link Unsafe}. |
25 | 26 | * NOTE: This implementation is designed for Java 9. Although it should work with earlier Java releases, it is better to |
26 | 27 | * use {@link PreJava9ReflectionAccessor} for them. |
27 | 28 | */ |
29 | @SuppressWarnings({"unchecked", "rawtypes"}) | |
28 | 30 | final class UnsafeReflectionAccessor extends ReflectionAccessor { |
29 | 31 | |
30 | private final Unsafe theUnsafe = getUnsafeInstance(); | |
32 | private static Class unsafeClass; | |
33 | private final Object theUnsafe = getUnsafeInstance(); | |
31 | 34 | private final Field overrideField = getOverrideField(); |
32 | 35 | |
33 | /** | |
34 | * {@inheritDoc} | |
35 | */ | |
36 | /** {@inheritDoc} */ | |
36 | 37 | @Override |
37 | 38 | public void makeAccessible(AccessibleObject ao) { |
38 | if (theUnsafe != null && overrideField != null) { | |
39 | long overrideOffset = theUnsafe.objectFieldOffset(overrideField); | |
40 | theUnsafe.putBoolean(ao, overrideOffset, true); | |
39 | boolean success = makeAccessibleWithUnsafe(ao); | |
40 | if (!success) { | |
41 | try { | |
42 | // unsafe couldn't be found, so try using accessible anyway | |
43 | ao.setAccessible(true); | |
44 | } catch (SecurityException e) { | |
45 | throw new JsonIOException("Gson couldn't modify fields for " + ao | |
46 | + "\nand sun.misc.Unsafe not found.\nEither write a custom type adapter," | |
47 | + " or make fields accessible, or include sun.misc.Unsafe.", e); | |
48 | } | |
41 | 49 | } |
42 | 50 | } |
43 | 51 | |
44 | private static Unsafe getUnsafeInstance() { | |
52 | // Visible for testing only | |
53 | boolean makeAccessibleWithUnsafe(AccessibleObject ao) { | |
54 | if (theUnsafe != null && overrideField != null) { | |
55 | try { | |
56 | Method method = unsafeClass.getMethod("objectFieldOffset", Field.class); | |
57 | long overrideOffset = (Long) method.invoke(theUnsafe, overrideField); // long overrideOffset = theUnsafe.objectFieldOffset(overrideField); | |
58 | Method putBooleanMethod = unsafeClass.getMethod("putBoolean", Object.class, long.class, boolean.class); | |
59 | putBooleanMethod.invoke(theUnsafe, ao, overrideOffset, true); // theUnsafe.putBoolean(ao, overrideOffset, true); | |
60 | return true; | |
61 | } catch (Exception ignored) { // do nothing | |
62 | } | |
63 | } | |
64 | return false; | |
65 | } | |
66 | ||
67 | private static Object getUnsafeInstance() { | |
45 | 68 | try { |
46 | Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); | |
69 | unsafeClass = Class.forName("sun.misc.Unsafe"); | |
70 | Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); | |
47 | 71 | unsafeField.setAccessible(true); |
48 | return (Unsafe) unsafeField.get(null); | |
72 | return unsafeField.get(null); | |
49 | 73 | } catch (Exception e) { |
50 | e.printStackTrace(); | |
51 | 74 | return null; |
52 | 75 | } |
53 | 76 | } |
56 | 79 | try { |
57 | 80 | return AccessibleObject.class.getDeclaredField("override"); |
58 | 81 | } catch (NoSuchFieldException e) { |
59 | e.printStackTrace(); | |
60 | 82 | return null; |
61 | 83 | } |
62 | 84 | } |
62 | 62 | + target.someConstantStringInstanceField + "\"}", gson.toJson(target)); |
63 | 63 | } |
64 | 64 | |
65 | public void testGsonWithLowerCaseDotPolicySerialization() { | |
66 | Gson gson = builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DOTS).create(); | |
67 | StringWrapper target = new StringWrapper("blah"); | |
68 | assertEquals("{\"some.constant.string.instance.field\":\"" | |
69 | + target.someConstantStringInstanceField + "\"}", gson.toJson(target)); | |
70 | } | |
71 | ||
72 | public void testGsonWithLowerCaseDotPolicyDeserialiation() { | |
73 | Gson gson = builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DOTS).create(); | |
74 | String target = "{\"some.constant.string.instance.field\":\"someValue\"}"; | |
75 | StringWrapper deserializedObject = gson.fromJson(target, StringWrapper.class); | |
76 | assertEquals("someValue", deserializedObject.someConstantStringInstanceField); | |
77 | } | |
78 | ||
65 | 79 | public void testGsonWithLowerCaseDashPolicyDeserialiation() { |
66 | 80 | Gson gson = builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create(); |
67 | 81 | String target = "{\"some-constant-string-instance-field\":\"someValue\"}"; |
+51
-0
0 | /* | |
1 | * Copyright (C) 2018 The Gson authors | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | */ | |
15 | package com.google.gson.internal.reflect; | |
16 | ||
17 | import static org.junit.Assert.assertTrue; | |
18 | import static org.junit.Assert.fail; | |
19 | ||
20 | import java.lang.reflect.Field; | |
21 | ||
22 | import org.junit.Test; | |
23 | ||
24 | /** | |
25 | * Unit tests for {@link UnsafeReflectionAccessor} | |
26 | * | |
27 | * @author Inderjeet Singh | |
28 | */ | |
29 | public class UnsafeReflectionAccessorTest { | |
30 | ||
31 | @Test | |
32 | public void testMakeAccessibleWithUnsafe() throws Exception { | |
33 | UnsafeReflectionAccessor accessor = new UnsafeReflectionAccessor(); | |
34 | Field field = ClassWithPrivateFinalFields.class.getDeclaredField("a"); | |
35 | try { | |
36 | boolean success = accessor.makeAccessibleWithUnsafe(field); | |
37 | assertTrue(success); | |
38 | } catch (Exception e) { | |
39 | fail("Unsafe didn't work on the JDK"); | |
40 | } | |
41 | } | |
42 | ||
43 | @SuppressWarnings("unused") | |
44 | private static final class ClassWithPrivateFinalFields { | |
45 | private final String a; | |
46 | public ClassWithPrivateFinalFields(String a) { | |
47 | this.a = a; | |
48 | } | |
49 | } | |
50 | } |
10 | 10 | |
11 | 11 | <groupId>com.google.code.gson</groupId> |
12 | 12 | <artifactId>gson-parent</artifactId> |
13 | <version>2.8.3</version> | |
13 | <version>2.8.4</version> | |
14 | 14 | <packaging>pom</packaging> |
15 | 15 | |
16 | 16 | <name>Gson Parent</name> |
30 | 30 | <url>https://github.com/google/gson/</url> |
31 | 31 | <connection>scm:git:https://github.com/google/gson.git</connection> |
32 | 32 | <developerConnection>scm:git:git@github.com:google/gson.git</developerConnection> |
33 | <tag>gson-parent-2.8.3</tag> | |
33 | <tag>gson-parent-2.8.4</tag> | |
34 | 34 | </scm> |
35 | 35 | |
36 | 36 | <issueManagement> |
0 | include ':gson' |