-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4065 from square/jw.mr-jars.2024-01-26
Clean up `Platform` to be more maintainable
- Loading branch information
Showing
31 changed files
with
380 additions
and
370 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Retrofit Java Tests | ||
|
||
These are in a separate module for two reasons: | ||
|
||
- It ensures optional dependencies (Kotlin stuff) are completely absent. | ||
- It uses the multi-release jar on the classpath rather than only the classes folder. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
apply plugin: 'java-library' | ||
|
||
dependencies { | ||
testImplementation projects.retrofit | ||
testImplementation projects.retrofit.testHelpers | ||
testImplementation libs.junit | ||
testImplementation libs.truth | ||
testImplementation libs.guava | ||
testImplementation libs.mockwebserver | ||
} | ||
|
||
// Create a test task for each supported JDK. | ||
(8..21).each { majorVersion -> | ||
def jdkTest = tasks.register("testJdk$majorVersion", Test) { | ||
javaLauncher = javaToolchains.launcherFor { | ||
languageVersion = JavaLanguageVersion.of(majorVersion) | ||
vendor = JvmVendorSpec.AZUL | ||
} | ||
|
||
description = "Runs the test suite on JDK $majorVersion" | ||
group = LifecycleBasePlugin.VERIFICATION_GROUP | ||
|
||
// Copy inputs from normal Test task. | ||
def testTask = tasks.getByName("test") | ||
classpath = testTask.classpath | ||
testClassesDirs = testTask.testClassesDirs | ||
} | ||
tasks.named("check").configure { | ||
dependsOn(jdkTest) | ||
} | ||
} | ||
|
||
// We don't need the built-in task which uses Gradle's JVM given the above variants. | ||
tasks.getByName('test').enabled = false |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright (C) 2013 Square, 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 retrofit2; | ||
|
||
import android.os.Handler; | ||
import android.os.Looper; | ||
import java.util.concurrent.Executor; | ||
|
||
final class AndroidMainExecutor implements Executor { | ||
private final Handler handler = new Handler(Looper.getMainLooper()); | ||
|
||
@Override | ||
public void execute(Runnable r) { | ||
handler.post(r); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright (C) 2024 Square, 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 retrofit2; | ||
|
||
import static java.util.Arrays.asList; | ||
import static java.util.Collections.emptyList; | ||
import static java.util.Collections.singletonList; | ||
|
||
import android.annotation.TargetApi; | ||
import java.util.List; | ||
import java.util.concurrent.Executor; | ||
import javax.annotation.Nullable; | ||
|
||
class BuiltInFactories { | ||
List<? extends CallAdapter.Factory> createDefaultCallAdapterFactories( | ||
@Nullable Executor callbackExecutor) { | ||
return singletonList(new DefaultCallAdapterFactory(callbackExecutor)); | ||
} | ||
|
||
List<? extends Converter.Factory> createDefaultConverterFactories() { | ||
return emptyList(); | ||
} | ||
|
||
@TargetApi(24) | ||
static final class Java8 extends BuiltInFactories { | ||
@Override | ||
List<? extends CallAdapter.Factory> createDefaultCallAdapterFactories( | ||
@Nullable Executor callbackExecutor) { | ||
return asList( | ||
new CompletableFutureCallAdapterFactory(), | ||
new DefaultCallAdapterFactory(callbackExecutor)); | ||
} | ||
|
||
@Override | ||
List<? extends Converter.Factory> createDefaultConverterFactories() { | ||
return singletonList(new OptionalConverterFactory()); | ||
} | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
retrofit/src/main/java/retrofit2/DefaultMethodSupport.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (C) 2024 Square, 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 retrofit2; | ||
|
||
import android.annotation.TargetApi; | ||
import android.os.Build; | ||
import java.lang.reflect.Method; | ||
import javax.annotation.Nullable; | ||
|
||
class DefaultMethodSupport { | ||
boolean isDefaultMethod(Method method) { | ||
return false; | ||
} | ||
|
||
@Nullable | ||
Object invokeDefaultMethod( | ||
Method method, Class<?> declaringClass, Object proxy, @Nullable Object[] args) | ||
throws Throwable { | ||
throw new AssertionError(); | ||
} | ||
|
||
/** | ||
* Android does not support MR jars, so this extends the baseline JVM support which targets | ||
* Java 8 APIs. Default methods and the reflection API to detect them were added to API 24 | ||
* as part of the initial Java 8 set. MethodHandle, our means of invoking the default method | ||
* through the proxy, was not added until API 26. | ||
*/ | ||
@TargetApi(24) | ||
static final class Android24 extends DefaultMethodSupportJvm { | ||
@Override | ||
Object invokeDefaultMethod( | ||
Method method, Class<?> declaringClass, Object proxy, @Nullable Object[] args) | ||
throws Throwable { | ||
if (Build.VERSION.SDK_INT < 26) { | ||
throw new UnsupportedOperationException( | ||
"Calling default methods on API 24 and 25 is not supported"); | ||
} | ||
return super.invokeDefaultMethod(method, declaringClass, proxy, args); | ||
} | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
retrofit/src/main/java/retrofit2/DefaultMethodSupportJvm.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* Copyright (C) 2024 Square, 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 retrofit2; | ||
|
||
import java.lang.invoke.MethodHandles.Lookup; | ||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.Method; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* From Java 8 to Java 13, the only way to invoke a default method on a proxied interface is by | ||
* reflectively creating a trusted {@link Lookup} to invoke a method handle. | ||
* <p> | ||
* Note: This class has multi-release jar variants for newer versions of Java. | ||
*/ | ||
class DefaultMethodSupportJvm extends DefaultMethodSupport { | ||
private @Nullable Constructor<Lookup> lookupConstructor; | ||
|
||
@Override | ||
boolean isDefaultMethod(Method method) { | ||
return method.isDefault(); | ||
} | ||
|
||
@Override | ||
Object invokeDefaultMethod( | ||
Method method, Class<?> declaringClass, Object proxy, @Nullable Object[] args) | ||
throws Throwable { | ||
Constructor<Lookup> lookupConstructor = this.lookupConstructor; | ||
if (lookupConstructor == null) { | ||
lookupConstructor = Lookup.class.getDeclaredConstructor(Class.class, int.class); | ||
lookupConstructor.setAccessible(true); | ||
this.lookupConstructor = lookupConstructor; | ||
} | ||
return lookupConstructor | ||
.newInstance(declaringClass, -1 /* trusted */) | ||
.unreflectSpecial(method, declaringClass) | ||
.bindTo(proxy) | ||
.invokeWithArguments(args); | ||
} | ||
} |
Oops, something went wrong.