Merge branch 'master' into optional-sql
This commit is contained in:
commit
69173b02ea
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "maven"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
16
CHANGELOG.md
16
CHANGELOG.md
@ -1,6 +1,22 @@
|
|||||||
Change Log
|
Change Log
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
## Version 2.8.8
|
||||||
|
|
||||||
|
* Fixed issue with recursive types (#1390).
|
||||||
|
* Better behaviour with Java 9+ and `Unsafe` if there is a security manager (#1712).
|
||||||
|
* `EnumTypeAdapter` now works better when ProGuard has obfuscated enum fields (#1495).
|
||||||
|
|
||||||
|
## Version 2.8.7
|
||||||
|
|
||||||
|
* Fixed `ISO8601UtilsTest` failing on systems with UTC+X.
|
||||||
|
* Improved javadoc for `JsonStreamParser`.
|
||||||
|
* Updated proguard.cfg (#1693).
|
||||||
|
* Fixed `IllegalStateException` in `JsonTreeWriter` (#1592).
|
||||||
|
* Added `JsonArray.isEmpty()` (#1640).
|
||||||
|
* Added new test cases (#1638).
|
||||||
|
* Fixed OSGi metadata generation to work on JavaSE < 9 (#1603).
|
||||||
|
|
||||||
## Version 2.8.6
|
## Version 2.8.6
|
||||||
_2019-10-04_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6)
|
_2019-10-04_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6)
|
||||||
* Added static methods `JsonParser.parseString` and `JsonParser.parseReader` and deprecated instance method `JsonParser.parse`
|
* Added static methods `JsonParser.parseString` and `JsonParser.parseReader` and deprecated instance method `JsonParser.parse`
|
||||||
|
@ -17,7 +17,7 @@ There are a few open-source projects that can convert Java objects to JSON. Howe
|
|||||||
Gradle:
|
Gradle:
|
||||||
```gradle
|
```gradle
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.google.code.gson:gson:2.8.6'
|
implementation 'com.google.code.gson:gson:2.8.8'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ Maven:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.8.6</version>
|
<version>2.8.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ The Gson instance does not maintain any state while invoking Json operations. So
|
|||||||
## <a name="TOC-Gson-With-Gradle"></a>Using Gson with Gradle/Android
|
## <a name="TOC-Gson-With-Gradle"></a>Using Gson with Gradle/Android
|
||||||
```
|
```
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.google.code.gson:gson:2.8.6'
|
implementation 'com.google.code.gson:gson:2.8.8'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## <a name="TOC-Gson-With-Maven"></a>Using Gson with Maven
|
## <a name="TOC-Gson-With-Maven"></a>Using Gson with Maven
|
||||||
@ -86,7 +86,7 @@ To use Gson with Maven2/3, you can use the Gson version available in Maven Centr
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.8.6</version>
|
<version>2.8.8</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.2</version>
|
<version>4.13.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
|
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
|
||||||
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
|
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
|
||||||
-keep class * implements com.google.gson.TypeAdapter
|
-keep class * extends com.google.gson.TypeAdapter
|
||||||
-keep class * implements com.google.gson.TypeAdapterFactory
|
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||||
-keep class * implements com.google.gson.JsonSerializer
|
-keep class * implements com.google.gson.JsonSerializer
|
||||||
-keep class * implements com.google.gson.JsonDeserializer
|
-keep class * implements com.google.gson.JsonDeserializer
|
||||||
@ -25,4 +25,8 @@
|
|||||||
@com.google.gson.annotations.SerializedName <fields>;
|
@com.google.gson.annotations.SerializedName <fields>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
|
||||||
|
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
|
||||||
|
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
|
||||||
|
|
||||||
##---------------End: proguard configuration for Gson ----------
|
##---------------End: proguard configuration for Gson ----------
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.2</version>
|
<version>4.13.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
91
gson/pom.xml
91
gson/pom.xml
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson-parent</artifactId>
|
<artifactId>gson-parent</artifactId>
|
||||||
<version>2.8.7-SNAPSHOT</version>
|
<version>2.8.9-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
@ -16,6 +16,12 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wvengen</groupId>
|
||||||
|
<artifactId>proguard-maven-plugin</artifactId>
|
||||||
|
<version>2.4.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -34,7 +40,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>biz.aQute.bnd</groupId>
|
<groupId>biz.aQute.bnd</groupId>
|
||||||
<artifactId>bnd-maven-plugin</artifactId>
|
<artifactId>bnd-maven-plugin</artifactId>
|
||||||
<version>4.0.0</version>
|
<version>5.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
@ -69,6 +75,87 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.coderplus.maven.plugins</groupId>
|
||||||
|
<artifactId>copy-rename-maven-plugin</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>pre-obfuscate-class</id>
|
||||||
|
<phase>process-test-classes</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>rename</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<sourceFile>${project.build.directory}/test-classes/com/google/gson/functional/EnumWithObfuscatedTest.class</sourceFile>
|
||||||
|
<destinationFile>${project.build.directory}/test-classes-obfuscated-injar/com/google/gson/functional/EnumWithObfuscatedTest.class</destinationFile>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<sourceFile>${project.build.directory}/test-classes/com/google/gson/functional/EnumWithObfuscatedTest$Gender.class</sourceFile>
|
||||||
|
<destinationFile>${project.build.directory}/test-classes-obfuscated-injar/com/google/gson/functional/EnumWithObfuscatedTest$Gender.class</destinationFile>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.github.wvengen</groupId>
|
||||||
|
<artifactId>proguard-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-test-classes</phase>
|
||||||
|
<goals><goal>proguard</goal></goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<proguardVersion>6.2.2</proguardVersion>
|
||||||
|
<obfuscate>true</obfuscate>
|
||||||
|
<injar>test-classes-obfuscated-injar</injar>
|
||||||
|
<outjar>test-classes-obfuscated-outjar</outjar>
|
||||||
|
<inFilter>**/*.class</inFilter>
|
||||||
|
<proguardInclude>${basedir}/src/test/resources/testcases-proguard.conf</proguardInclude>
|
||||||
|
<libs>
|
||||||
|
<lib>${project.build.directory}/classes</lib>
|
||||||
|
<lib>${java.home}/jmods/java.base.jmod</lib>
|
||||||
|
</libs>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.proguard</groupId>
|
||||||
|
<artifactId>proguard-base</artifactId>
|
||||||
|
<version>6.2.2</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>post-obfuscate-class</id>
|
||||||
|
<phase>process-test-classes</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/test-classes/com/google/gson/functional</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.build.directory}/test-classes-obfuscated-outjar/com/google/gson/functional</directory>
|
||||||
|
<includes>
|
||||||
|
<include>EnumWithObfuscatedTest.class</include>
|
||||||
|
<include>EnumWithObfuscatedTest$Gender.class</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -29,8 +29,9 @@ import com.google.gson.stream.MalformedJsonException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
|
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
|
||||||
* asynchronously.
|
* asynchronously. The JSON data is parsed in lenient mode, see also
|
||||||
*
|
* {@link JsonReader#setLenient(boolean)}.
|
||||||
|
*
|
||||||
* <p>This class is conditionally thread-safe (see Item 70, Effective Java second edition). To
|
* <p>This class is conditionally thread-safe (see Item 70, Effective Java second edition). To
|
||||||
* properly use this class across multiple threads, you will need to add some external
|
* properly use this class across multiple threads, you will need to add some external
|
||||||
* synchronization. For example:
|
* synchronization. For example:
|
||||||
@ -72,10 +73,12 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next available {@link JsonElement} on the reader. Null if none available.
|
* Returns the next available {@link JsonElement} on the reader. Throws a
|
||||||
*
|
* {@link NoSuchElementException} if no element is available.
|
||||||
* @return the next available {@link JsonElement} on the reader. Null if none available.
|
*
|
||||||
* @throws JsonParseException if the incoming stream is malformed JSON.
|
* @return the next available {@code JsonElement} on the reader.
|
||||||
|
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
|
||||||
|
* @throws NoSuchElementException if no {@code JsonElement} is available.
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public JsonElement next() throws JsonParseException {
|
public JsonElement next() throws JsonParseException {
|
||||||
@ -97,6 +100,7 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
|
|||||||
/**
|
/**
|
||||||
* Returns true if a {@link JsonElement} is available on the input for consumption
|
* Returns true if a {@link JsonElement} is available on the input for consumption
|
||||||
* @return true if a {@link JsonElement} is available on the input, false otherwise
|
* @return true if a {@link JsonElement} is available on the input, false otherwise
|
||||||
|
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
|
@ -25,7 +25,12 @@ import java.lang.reflect.ParameterizedType;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.lang.reflect.WildcardType;
|
import java.lang.reflect.WildcardType;
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static com.google.gson.internal.$Gson$Preconditions.checkArgument;
|
import static com.google.gson.internal.$Gson$Preconditions.checkArgument;
|
||||||
import static com.google.gson.internal.$Gson$Preconditions.checkNotNull;
|
import static com.google.gson.internal.$Gson$Preconditions.checkNotNull;
|
||||||
@ -334,52 +339,62 @@ public final class $Gson$Types {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
|
public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
|
||||||
return resolve(context, contextRawType, toResolve, new HashSet<TypeVariable<?>>());
|
|
||||||
|
return resolve(context, contextRawType, toResolve, new HashMap<TypeVariable<?>, Type>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Type resolve(Type context, Class<?> contextRawType, Type toResolve,
|
private static Type resolve(Type context, Class<?> contextRawType, Type toResolve,
|
||||||
Collection<TypeVariable<?>> visitedTypeVariables) {
|
Map<TypeVariable<?>, Type> visitedTypeVariables) {
|
||||||
// this implementation is made a little more complicated in an attempt to avoid object-creation
|
// this implementation is made a little more complicated in an attempt to avoid object-creation
|
||||||
|
TypeVariable<?> resolving = null;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (toResolve instanceof TypeVariable) {
|
if (toResolve instanceof TypeVariable) {
|
||||||
TypeVariable<?> typeVariable = (TypeVariable<?>) toResolve;
|
TypeVariable<?> typeVariable = (TypeVariable<?>) toResolve;
|
||||||
if (visitedTypeVariables.contains(typeVariable)) {
|
Type previouslyResolved = visitedTypeVariables.get(typeVariable);
|
||||||
|
if (previouslyResolved != null) {
|
||||||
// cannot reduce due to infinite recursion
|
// cannot reduce due to infinite recursion
|
||||||
return toResolve;
|
return (previouslyResolved == Void.TYPE) ? toResolve : previouslyResolved;
|
||||||
} else {
|
|
||||||
visitedTypeVariables.add(typeVariable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert a placeholder to mark the fact that we are in the process of resolving this type
|
||||||
|
visitedTypeVariables.put(typeVariable, Void.TYPE);
|
||||||
|
if (resolving == null) {
|
||||||
|
resolving = typeVariable;
|
||||||
|
}
|
||||||
|
|
||||||
toResolve = resolveTypeVariable(context, contextRawType, typeVariable);
|
toResolve = resolveTypeVariable(context, contextRawType, typeVariable);
|
||||||
if (toResolve == typeVariable) {
|
if (toResolve == typeVariable) {
|
||||||
return toResolve;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (toResolve instanceof Class && ((Class<?>) toResolve).isArray()) {
|
} else if (toResolve instanceof Class && ((Class<?>) toResolve).isArray()) {
|
||||||
Class<?> original = (Class<?>) toResolve;
|
Class<?> original = (Class<?>) toResolve;
|
||||||
Type componentType = original.getComponentType();
|
Type componentType = original.getComponentType();
|
||||||
Type newComponentType = resolve(context, contextRawType, componentType, visitedTypeVariables);
|
Type newComponentType = resolve(context, contextRawType, componentType, visitedTypeVariables);
|
||||||
return componentType == newComponentType
|
toResolve = equal(componentType, newComponentType)
|
||||||
? original
|
? original
|
||||||
: arrayOf(newComponentType);
|
: arrayOf(newComponentType);
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (toResolve instanceof GenericArrayType) {
|
} else if (toResolve instanceof GenericArrayType) {
|
||||||
GenericArrayType original = (GenericArrayType) toResolve;
|
GenericArrayType original = (GenericArrayType) toResolve;
|
||||||
Type componentType = original.getGenericComponentType();
|
Type componentType = original.getGenericComponentType();
|
||||||
Type newComponentType = resolve(context, contextRawType, componentType, visitedTypeVariables);
|
Type newComponentType = resolve(context, contextRawType, componentType, visitedTypeVariables);
|
||||||
return componentType == newComponentType
|
toResolve = equal(componentType, newComponentType)
|
||||||
? original
|
? original
|
||||||
: arrayOf(newComponentType);
|
: arrayOf(newComponentType);
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (toResolve instanceof ParameterizedType) {
|
} else if (toResolve instanceof ParameterizedType) {
|
||||||
ParameterizedType original = (ParameterizedType) toResolve;
|
ParameterizedType original = (ParameterizedType) toResolve;
|
||||||
Type ownerType = original.getOwnerType();
|
Type ownerType = original.getOwnerType();
|
||||||
Type newOwnerType = resolve(context, contextRawType, ownerType, visitedTypeVariables);
|
Type newOwnerType = resolve(context, contextRawType, ownerType, visitedTypeVariables);
|
||||||
boolean changed = newOwnerType != ownerType;
|
boolean changed = !equal(newOwnerType, ownerType);
|
||||||
|
|
||||||
Type[] args = original.getActualTypeArguments();
|
Type[] args = original.getActualTypeArguments();
|
||||||
for (int t = 0, length = args.length; t < length; t++) {
|
for (int t = 0, length = args.length; t < length; t++) {
|
||||||
Type resolvedTypeArgument = resolve(context, contextRawType, args[t], visitedTypeVariables);
|
Type resolvedTypeArgument = resolve(context, contextRawType, args[t], visitedTypeVariables);
|
||||||
if (resolvedTypeArgument != args[t]) {
|
if (!equal(resolvedTypeArgument, args[t])) {
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
args = args.clone();
|
args = args.clone();
|
||||||
changed = true;
|
changed = true;
|
||||||
@ -388,9 +403,10 @@ public final class $Gson$Types {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed
|
toResolve = changed
|
||||||
? newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
|
? newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
|
||||||
: original;
|
: original;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (toResolve instanceof WildcardType) {
|
} else if (toResolve instanceof WildcardType) {
|
||||||
WildcardType original = (WildcardType) toResolve;
|
WildcardType original = (WildcardType) toResolve;
|
||||||
@ -400,20 +416,28 @@ public final class $Gson$Types {
|
|||||||
if (originalLowerBound.length == 1) {
|
if (originalLowerBound.length == 1) {
|
||||||
Type lowerBound = resolve(context, contextRawType, originalLowerBound[0], visitedTypeVariables);
|
Type lowerBound = resolve(context, contextRawType, originalLowerBound[0], visitedTypeVariables);
|
||||||
if (lowerBound != originalLowerBound[0]) {
|
if (lowerBound != originalLowerBound[0]) {
|
||||||
return supertypeOf(lowerBound);
|
toResolve = supertypeOf(lowerBound);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (originalUpperBound.length == 1) {
|
} else if (originalUpperBound.length == 1) {
|
||||||
Type upperBound = resolve(context, contextRawType, originalUpperBound[0], visitedTypeVariables);
|
Type upperBound = resolve(context, contextRawType, originalUpperBound[0], visitedTypeVariables);
|
||||||
if (upperBound != originalUpperBound[0]) {
|
if (upperBound != originalUpperBound[0]) {
|
||||||
return subtypeOf(upperBound);
|
toResolve = subtypeOf(upperBound);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return original;
|
toResolve = original;
|
||||||
|
break;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return toResolve;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ensure that any in-process resolution gets updated with the final result
|
||||||
|
if (resolving != null) {
|
||||||
|
visitedTypeVariables.put(resolving, toResolve);
|
||||||
|
}
|
||||||
|
return toResolve;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type resolveTypeVariable(Type context, Class<?> contextRawType, TypeVariable<?> unknown) {
|
static Type resolveTypeVariable(Type context, Class<?> contextRawType, TypeVariable<?> unknown) {
|
||||||
|
@ -17,12 +17,15 @@
|
|||||||
package com.google.gson.internal.bind;
|
package com.google.gson.internal.bind;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -753,9 +756,20 @@ public final class TypeAdapters {
|
|||||||
|
|
||||||
public EnumTypeAdapter(Class<T> classOfT) {
|
public EnumTypeAdapter(Class<T> classOfT) {
|
||||||
try {
|
try {
|
||||||
for (T constant : classOfT.getEnumConstants()) {
|
for (final Field field : classOfT.getDeclaredFields()) {
|
||||||
|
if (!field.isEnumConstant()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||||
|
@Override public Void run() {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
T constant = (T)(field.get(null));
|
||||||
String name = constant.name();
|
String name = constant.name();
|
||||||
SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
|
SerializedName annotation = field.getAnnotation(SerializedName.class);
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
name = annotation.value();
|
name = annotation.value();
|
||||||
for (String alternate : annotation.alternate()) {
|
for (String alternate : annotation.alternate()) {
|
||||||
@ -765,7 +779,7 @@ public final class TypeAdapters {
|
|||||||
nameToConstant.put(name, constant);
|
nameToConstant.put(name, constant);
|
||||||
constantToName.put(constant, name);
|
constantToName.put(constant, name);
|
||||||
}
|
}
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ final class UnsafeReflectionAccessor extends ReflectionAccessor {
|
|||||||
private static Field getOverrideField() {
|
private static Field getOverrideField() {
|
||||||
try {
|
try {
|
||||||
return AccessibleObject.class.getDeclaredField("override");
|
return AccessibleObject.class.getDeclaredField("override");
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,8 @@
|
|||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import com.google.gson.common.MoreAsserts;
|
import com.google.gson.common.MoreAsserts;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jesse Wilson
|
* @author Jesse Wilson
|
||||||
@ -99,4 +98,68 @@ public final class JsonArrayTest extends TestCase {
|
|||||||
assertEquals(1, original.get(0).getAsJsonArray().size());
|
assertEquals(1, original.get(0).getAsJsonArray().size());
|
||||||
assertEquals(0, copy.get(0).getAsJsonArray().size());
|
assertEquals(0, copy.get(0).getAsJsonArray().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testFailedGetArrayValues() {
|
||||||
|
JsonArray jsonArray = new JsonArray();
|
||||||
|
jsonArray.add(JsonParser.parseString("{" + "\"key1\":\"value1\"," + "\"key2\":\"value2\"," + "\"key3\":\"value3\"," + "\"key4\":\"value4\"" + "}"));
|
||||||
|
try {
|
||||||
|
jsonArray.getAsBoolean();
|
||||||
|
fail("expected getBoolean to fail");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"JsonObject", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonArray.get(-1);
|
||||||
|
fail("expected get to fail");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"Index -1 out of bounds for length 1", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonArray.getAsString();
|
||||||
|
fail("expected getString to fail");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"JsonObject", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonArray.remove(0);
|
||||||
|
jsonArray.add("hello");
|
||||||
|
try {
|
||||||
|
jsonArray.getAsDouble();
|
||||||
|
fail("expected getDouble to fail");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"For input string: \"hello\"", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonArray.getAsInt();
|
||||||
|
fail("expected getInt to fail");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"For input string: \"hello\"", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonArray.get(0).getAsJsonArray();
|
||||||
|
fail("expected getJSONArray to fail");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"Not a JSON Array: \"hello\"", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonArray.getAsJsonObject();
|
||||||
|
fail("expected getJSONObject to fail");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"Not a JSON Object: [\"hello\"]", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonArray.getAsLong();
|
||||||
|
fail("expected getLong to fail");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
assertEquals("Expected an exception message",
|
||||||
|
"For input string: \"hello\"", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed 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 com.google.gson.functional;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functional tests for enums with Proguard.
|
||||||
|
*
|
||||||
|
* @author Young Cha
|
||||||
|
*/
|
||||||
|
public class EnumWithObfuscatedTest extends TestCase {
|
||||||
|
private Gson gson;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
gson = new Gson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Gender {
|
||||||
|
@SerializedName("MAIL")
|
||||||
|
MALE,
|
||||||
|
|
||||||
|
@SerializedName("FEMAIL")
|
||||||
|
FEMALE
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEnumClassWithObfuscated() {
|
||||||
|
for (Gender enumConstant: Gender.class.getEnumConstants()) {
|
||||||
|
try {
|
||||||
|
Gender.class.getField(enumConstant.name());
|
||||||
|
fail("Enum is not obfuscated");
|
||||||
|
} catch (NoSuchFieldException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(Gender.MALE, gson.fromJson("\"MAIL\"", Gender.class));
|
||||||
|
assertEquals("\"MAIL\"", gson.toJson(Gender.MALE, Gender.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.google.gson.functional;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test covers the scenario described in #1390 where a type variable needs to be used
|
||||||
|
* by a type definition multiple times. Both type variable references should resolve to the
|
||||||
|
* same underlying concrete type.
|
||||||
|
*/
|
||||||
|
public class ReusedTypeVariablesFullyResolveTest {
|
||||||
|
|
||||||
|
private Gson gson;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
gson = new GsonBuilder().create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") // The instances were being unmarshaled as Strings instead of TestEnums
|
||||||
|
@Test
|
||||||
|
public void testGenericsPreservation() {
|
||||||
|
TestEnumSetCollection withSet = gson.fromJson("{\"collection\":[\"ONE\",\"THREE\"]}", TestEnumSetCollection.class);
|
||||||
|
Iterator<TestEnum> iterator = withSet.collection.iterator();
|
||||||
|
assertNotNull(withSet);
|
||||||
|
assertNotNull(withSet.collection);
|
||||||
|
assertEquals(2, withSet.collection.size());
|
||||||
|
TestEnum first = iterator.next();
|
||||||
|
TestEnum second = iterator.next();
|
||||||
|
|
||||||
|
assertTrue(first instanceof TestEnum);
|
||||||
|
assertTrue(second instanceof TestEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TestEnum { ONE, TWO, THREE }
|
||||||
|
|
||||||
|
private static class TestEnumSetCollection extends SetCollection<TestEnum> {}
|
||||||
|
|
||||||
|
private static class SetCollection<T> extends BaseCollection<T, Set<T>> {}
|
||||||
|
|
||||||
|
private static class BaseCollection<U, C extends Collection<U>>
|
||||||
|
{
|
||||||
|
public C collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,9 +15,25 @@ public class ISO8601UtilsTest {
|
|||||||
@Rule
|
@Rule
|
||||||
public final ExpectedException exception = ExpectedException.none();
|
public final ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
|
private static TimeZone utcTimeZone() {
|
||||||
|
return TimeZone.getTimeZone("UTC");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GregorianCalendar createUtcCalendar() {
|
||||||
|
TimeZone utc = utcTimeZone();
|
||||||
|
GregorianCalendar calendar = new GregorianCalendar(utc);
|
||||||
|
// Calendar was created with current time, must clear it
|
||||||
|
calendar.clear();
|
||||||
|
return calendar;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDateFormatString() {
|
public void testDateFormatString() {
|
||||||
Date date = new GregorianCalendar(2018, Calendar.JUNE, 25).getTime();
|
GregorianCalendar calendar = new GregorianCalendar(utcTimeZone(), Locale.US);
|
||||||
|
// Calendar was created with current time, must clear it
|
||||||
|
calendar.clear();
|
||||||
|
calendar.set(2018, Calendar.JUNE, 25);
|
||||||
|
Date date = calendar.getTime();
|
||||||
String dateStr = ISO8601Utils.format(date);
|
String dateStr = ISO8601Utils.format(date);
|
||||||
String expectedDate = "2018-06-25";
|
String expectedDate = "2018-06-25";
|
||||||
assertEquals(expectedDate, dateStr.substring(0, expectedDate.length()));
|
assertEquals(expectedDate, dateStr.substring(0, expectedDate.length()));
|
||||||
@ -51,51 +67,28 @@ public class ISO8601UtilsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDateParseWithTimezone() throws ParseException {
|
public void testDateParseWithTimezone() throws ParseException {
|
||||||
TimeZone defaultTimeZone = TimeZone.getDefault();
|
String dateStr = "2018-06-25T00:00:00-03:00";
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
Date date = ISO8601Utils.parse(dateStr, new ParsePosition(0));
|
||||||
Locale defaultLocale = Locale.getDefault();
|
GregorianCalendar calendar = createUtcCalendar();
|
||||||
Locale.setDefault(Locale.US);
|
calendar.set(2018, Calendar.JUNE, 25, 3, 0);
|
||||||
try {
|
Date expectedDate = calendar.getTime();
|
||||||
String dateStr = "2018-06-25T00:00:00-03:00";
|
assertEquals(expectedDate, date);
|
||||||
Date date = ISO8601Utils.parse(dateStr, new ParsePosition(0));
|
|
||||||
Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime();
|
|
||||||
assertEquals(expectedDate, date);
|
|
||||||
} finally {
|
|
||||||
TimeZone.setDefault(defaultTimeZone);
|
|
||||||
Locale.setDefault(defaultLocale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDateParseSpecialTimezone() throws ParseException {
|
public void testDateParseSpecialTimezone() throws ParseException {
|
||||||
TimeZone defaultTimeZone = TimeZone.getDefault();
|
String dateStr = "2018-06-25T00:02:00-02:58";
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
Date date = ISO8601Utils.parse(dateStr, new ParsePosition(0));
|
||||||
Locale defaultLocale = Locale.getDefault();
|
GregorianCalendar calendar = createUtcCalendar();
|
||||||
Locale.setDefault(Locale.US);
|
calendar.set(2018, Calendar.JUNE, 25, 3, 0);
|
||||||
try {
|
Date expectedDate = calendar.getTime();
|
||||||
String dateStr = "2018-06-25T00:02:00-02:58";
|
assertEquals(expectedDate, date);
|
||||||
Date date = ISO8601Utils.parse(dateStr, new ParsePosition(0));
|
|
||||||
Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime();
|
|
||||||
assertEquals(expectedDate, date);
|
|
||||||
} finally {
|
|
||||||
TimeZone.setDefault(defaultTimeZone);
|
|
||||||
Locale.setDefault(defaultLocale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDateParseInvalidTime() throws ParseException {
|
public void testDateParseInvalidTime() throws ParseException {
|
||||||
TimeZone defaultTimeZone = TimeZone.getDefault();
|
String dateStr = "2018-06-25T61:60:62-03:00";
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
exception.expect(ParseException.class);
|
||||||
Locale defaultLocale = Locale.getDefault();
|
ISO8601Utils.parse(dateStr, new ParsePosition(0));
|
||||||
Locale.setDefault(Locale.US);
|
|
||||||
try {
|
|
||||||
String dateStr = "2018-06-25T61:60:62-03:00";
|
|
||||||
exception.expect(ParseException.class);
|
|
||||||
ISO8601Utils.parse(dateStr, new ParsePosition(0));
|
|
||||||
} finally {
|
|
||||||
TimeZone.setDefault(defaultTimeZone);
|
|
||||||
Locale.setDefault(defaultLocale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.gson.internal.reflect;
|
package com.google.gson.internal.reflect;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.security.Permission;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -41,6 +43,30 @@ public class UnsafeReflectionAccessorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMakeAccessibleWithRestrictiveSecurityManager() throws Exception {
|
||||||
|
final Permission accessDeclaredMembers = new RuntimePermission("accessDeclaredMembers");
|
||||||
|
final SecurityManager original = System.getSecurityManager();
|
||||||
|
SecurityManager restrictiveManager = new SecurityManager() {
|
||||||
|
@Override
|
||||||
|
public void checkPermission(Permission perm) {
|
||||||
|
if (accessDeclaredMembers.equals(perm)) {
|
||||||
|
throw new SecurityException("nope");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
System.setSecurityManager(restrictiveManager);
|
||||||
|
|
||||||
|
try {
|
||||||
|
UnsafeReflectionAccessor accessor = new UnsafeReflectionAccessor();
|
||||||
|
Field field = ClassWithPrivateFinalFields.class.getDeclaredField("a");
|
||||||
|
assertFalse("override field should have been inaccessible", accessor.makeAccessibleWithUnsafe(field));
|
||||||
|
accessor.makeAccessible(field);
|
||||||
|
} finally {
|
||||||
|
System.setSecurityManager(original);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static final class ClassWithPrivateFinalFields {
|
private static final class ClassWithPrivateFinalFields {
|
||||||
private final String a;
|
private final String a;
|
||||||
|
20
gson/src/test/resources/testcases-proguard.conf
Normal file
20
gson/src/test/resources/testcases-proguard.conf
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Options from Android Gradle Plugins
|
||||||
|
# https://android.googlesource.com/platform/tools/base/+/refs/heads/studio-master-dev/build-system/gradle-core/src/main/resources/com/android/build/gradle
|
||||||
|
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||||
|
-optimizationpasses 5
|
||||||
|
-allowaccessmodification
|
||||||
|
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep enum com.google.gson.functional.EnumWithObfuscatedTest$Gender
|
||||||
|
-keep class com.google.gson.functional.EnumWithObfuscatedTest {
|
||||||
|
public void test*();
|
||||||
|
protected void setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
-dontwarn com.google.gson.functional.EnumWithObfuscatedTest
|
||||||
|
-dontwarn junit.framework.TestCase
|
||||||
|
|
@ -51,7 +51,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.2</version>
|
<version>4.13.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
15
pom.xml
15
pom.xml
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson-parent</artifactId>
|
<artifactId>gson-parent</artifactId>
|
||||||
<version>2.8.7-SNAPSHOT</version>
|
<version>2.8.9-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>Gson Parent</name>
|
<name>Gson Parent</name>
|
||||||
@ -51,7 +51,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.12</version>
|
<version>4.13.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@ -97,7 +97,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>2.10.4</version>
|
<version>3.3.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
@ -106,7 +106,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>5.1.2</version>
|
||||||
<inherited>true</inherited>
|
<inherited>true</inherited>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
@ -117,10 +117,15 @@
|
|||||||
<artifactId>maven-release-plugin</artifactId>
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
<version>2.5.3</version>
|
<version>2.5.3</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.scm</groupId>
|
||||||
|
<artifactId>maven-scm-api</artifactId>
|
||||||
|
<version>1.11.3</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.scm</groupId>
|
<groupId>org.apache.maven.scm</groupId>
|
||||||
<artifactId>maven-scm-provider-gitexe</artifactId>
|
<artifactId>maven-scm-provider-gitexe</artifactId>
|
||||||
<version>1.9.5</version>
|
<version>1.11.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.12</version>
|
<version>4.13.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user