aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
diff options
context:
space:
mode:
authorGravatar cnsun <cnsun@google.com>2017-06-19 19:35:25 -0400
committerGravatar Kristina Chodorow <kchodorow@google.com>2017-06-20 14:35:37 -0400
commit9c931b3dfe204e5c25d016876c6ccb3ea55e7998 (patch)
tree83cea7ff5b617cb4a9e0e5a91afb06b419fad390 /src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
parentf0d730bcc7b1821c3db686a517be0d88206903c0 (diff)
Access interface constants to explicitly trigger the execution of interface
initializers. The problem is that when we desugar default methods, the static intializer of interface will not be executed. The JVM spec says that if an interface has default methods, then when it is loaded, it will also be initialized. After we desugar such an interface, its default methods are removed, and when we load the interface, the <clinit> will not be executed. This CL checks whether an interface has default methods and fields. If yes (needs to be initialized when the interface is loaded), it injects field access code to access the interface fields in the <clinit> of the companion class. We also create a constant $$CONSTANT$$ in the companion class. Then for all the classes that implement the interface, we inject GETSTATIC in the class <clinit> to the $$CONSTANT$$ of the companion class of the interface. This indirection is to avoid the IllegalAccessError when the interface is package private. Note that accessing an arbitrary interface field does not guarantee the interface will be initialized. We need to access the field that is initialized in the interface static initializer. RELNOTES: None PiperOrigin-RevId: 159496992
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
index bbba22e149..74dfa176a1 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -20,6 +20,7 @@ import static com.google.devtools.build.android.desugar.LambdaClassMaker.LAMBDA_
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import com.google.auto.value.AutoValue;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -625,7 +626,8 @@ class Desugar {
return ioPairListbuilder.build();
}
- private static class ThrowingClassLoader extends ClassLoader {
+ @VisibleForTesting
+ static class ThrowingClassLoader extends ClassLoader {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("java.")) {
@@ -700,7 +702,8 @@ class Desugar {
* closer.
*/
@SuppressWarnings("MustBeClosedChecker")
- private static ImmutableList<InputFileProvider> toRegisteredInputFileProvider(
+ @VisibleForTesting
+ static ImmutableList<InputFileProvider> toRegisteredInputFileProvider(
Closer closer, List<Path> paths) throws IOException {
ImmutableList.Builder<InputFileProvider> builder = new ImmutableList.Builder<>();
for (Path path : paths) {