Mark out an mmodule API surface / add bi-dir deps
This commit introduces the term "mmodule" in place of
"module" for the thing that is being prototyped;
"module" is a heavily overloaded term so
the extra "m" is intended to make it easier to track /
understand what "type of" module is involved.
Important parts of this commit:
+ {simple mmodule}.TestClass has been renamed to
DemoSimpleClass to distinguish it from a test and new
similar class being added in libart (DemoLibartClass).
+ Adds the @IntraCoreMModuleApi annotation; it is used to
indicate API members that form part of a "core" mmodule
contract (either incoming or outgoing dependency of a
libcore mmodule) that must be kept stable.
+ Annotates parts of the DemoSimpleClass to make them part
of the "simple mmodule API" contract.
+ Adds a method in the simple mmodule that isn't annotated
to demonstrate (Java) public methods that are not part
of the mmodule contract.
+ Includes a new target "core-simple.mmodule.stubs"
which generates the simple mmodule API stubs.
+ Includes a new target "core-all.mmodule.stubs"
which generates the mmodule API stubs for the core-all
library.
+ Adds bi-direction dependencies between parts of the
boot classpath. This makes the code a more realistic part
of "core" for prototyping / demostration purposes:
- DemoSimpleClass (now) has a method that calls through
to a method on DemoLibartClass to demonstrate a
dependency from {simple mmodule} onto core-libart.
- DemoLibartClass has a similar arrangement going in the
other direction making core-libart depend on {simple
mmodule} (making a bi-dir dependency but without an
infinite loop at runtime).
+ A test has been added for DemoLibartClass in the
CtsLibcoreSimpleMModuleTestCases to confirm the bi-dir
behavior in an automated test.
Bug: 113148576
Test: make checkbuild / make cts
Test: CTS: run cts -m CtsLibcoreSimpleModuleTestCases
Change-Id: I5564d6be61eba4c0116e91c601e32208da104f02
diff --git a/Android.bp b/Android.bp
index e220114..64df9ec 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,5 +1,5 @@
subdirs = [
- "modules/simple",
+ "mmodules/simple",
]
build = [
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index a728d61..c6b0855 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -16,21 +16,23 @@
// Definitions for building the Java library and associated tests.
//
-// libcore is divided into modules.
+// libcore has some sub-directories that follow a common structure:
+// e.g. dalvik, dom, harmony-tests, json, jsr166-tests, luni, libart, ojluni,
+// support, xml, xmlpull.
//
-// The structure of each module is:
+// The structure of these is generally:
//
// src/
// main/ # To be shipped on every device.
// java/ # Java source for library code.
-// native/ # C++ source for library code.
+// native/ # C/C++ source for library code.
// resources/ # Support files.
// test/ # Built only on demand, for testing.
// java/ # Java source for tests.
-// native/ # C++ source for tests (rare).
+// native/ # C/C++ source for tests (rare).
// resources/ # Support files.
//
-// All subdirectories are optional
+// All subdirectories are optional.
build = [
"openjdk_java_files.bp",
@@ -70,6 +72,7 @@
":openjdk_java_files",
":non_openjdk_java_files",
":android_icu4j_src_files",
+ ":core_simple_mmodule_java_files",
":openjdk_lambda_stub_files",
],
@@ -522,3 +525,41 @@
no_standard_libs: true,
system_modules: "none",
}
+
+//
+// Targets related to core mmodule APIs / dependencies.
+//
+
+// Generates stub source files for the {public SDK API + intra-core mmodule API}
+// of core-all.
+droiddoc {
+ name: "core-all-mmodule-stubs-docs",
+ srcs: [
+ ":openjdk_javadoc_files",
+ ":non_openjdk_javadoc_files",
+ ":android_icu4j_src_files_for_docs",
+ ":core_simple_mmodule_java_files",
+ ],
+
+ installable: false,
+ no_framework_libs: true,
+ metalava_enabled: true,
+ args: "-nodocs -stubsourceonly -showAnnotation libcore.mmodule.IntraCoreMModuleApi",
+}
+
+// A library containing the {public SDK API + intra-core mmodule API} stubs for
+// core-all.
+java_library {
+ name: "core-all.mmodule.stubs",
+ srcs: [
+ ":core-all-mmodule-stubs-docs",
+ ],
+ no_framework_libs: true,
+
+ no_standard_libs: true,
+ libs: ["core-all"],
+ system_modules: "core-all-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
diff --git a/luni/src/main/java/libcore/mmodule/DemoLibartClass.java b/luni/src/main/java/libcore/mmodule/DemoLibartClass.java
new file mode 100644
index 0000000..0a73f8e
--- /dev/null
+++ b/luni/src/main/java/libcore/mmodule/DemoLibartClass.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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 libcore.mmodule;
+
+import libcore.mmodule.IntraCoreMModuleApi;
+import libcore.mmodule.simple.DemoSimpleClass;
+
+/**
+ * A class that provides a dependency within core-libart for the core-simple mmodule to depend on,
+ * and depends on the core-simple mmodule thereby demonstrating a bi-directional dependency.
+ *
+ * @hide
+ */
+@IntraCoreMModuleApi
+public class DemoLibartClass {
+
+ private DemoLibartClass() {}
+
+ /**
+ * A method that depends on the simple mmodule to work.
+ *
+ * @hide
+ */
+ @IntraCoreMModuleApi // Exposed for tests
+ public static String intraCoreDependencyMethod() {
+ // Delegate to core-simple code to implement the method.
+ return DemoSimpleClass.simpleMethod();
+ }
+
+ /**
+ * A simple method that has no native or data file dependencies but is part of the intra-core
+ * mmodule API contract.
+ *
+ * @hide
+ */
+ @IntraCoreMModuleApi
+ public static String simpleMethod() {
+ return "Hello World";
+ }
+
+ /**
+ * A method that is public but not part of the intra-core mmodule API contract, i.e. it cannot
+ * be used from an mmodule.
+ *
+ * @hide
+ */
+ public static String hiddenMethod() {
+ return "Hello World";
+ }
+}
diff --git a/luni/src/main/java/libcore/mmodule/IntraCoreMModuleApi.java b/luni/src/main/java/libcore/mmodule/IntraCoreMModuleApi.java
new file mode 100644
index 0000000..1bcf005
--- /dev/null
+++ b/luni/src/main/java/libcore/mmodule/IntraCoreMModuleApi.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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 libcore.mmodule;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is part of a contract within the "core" set of libraries, some of which may
+ * be mmodules.
+ * <p>
+ * This annotation should only appear on API that is already marked <pre>@hide</pre>.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface IntraCoreMModuleApi {
+}
diff --git a/mmodules/simple/Android.bp b/mmodules/simple/Android.bp
new file mode 100644
index 0000000..e210ffd
--- /dev/null
+++ b/mmodules/simple/Android.bp
@@ -0,0 +1,113 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// 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.
+
+filegroup {
+ name: "core_simple_mmodule_java_files",
+ srcs: ["src/main/java/**/*.java"]
+}
+
+java_defaults {
+ name: "core-simple-mmodule-defaults",
+ srcs: [":core_simple_mmodule_java_files"],
+ installable: true,
+ no_framework_libs: true,
+
+ // As a logical part of the set of core-* libs we cannot use
+ // no_standard_libs: false here because core-simple is one of the default
+ // standard libs and that leads to a cycle. core-simple can depend on
+ // core-oj and core-libart and there can be dependencies from core-libart
+ // or core-oj back onto core-simple. So, we deliberately compile against
+ // core-all to avoid cycles.
+ no_standard_libs: true,
+ libs: ["core-all"],
+ system_modules: "core-all-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+
+ dxflags: ["--core-library"],
+}
+
+// A library containing the implementation of the core-simple mmodule.
+java_library {
+ name: "core-simple",
+ hostdex: true,
+ defaults: ["core-simple-mmodule-defaults"],
+}
+
+// A guaranteed unstripped version of core-simple.
+// The build system may or may not strip the core-simple jar
+// but this will not be stripped. See b/24535627.
+java_library {
+ name: "core-simple-testdex",
+ defaults: ["core-simple-mmodule-defaults"],
+ dex_preopt: {
+ enabled: false,
+ },
+}
+
+// Tests associated with the core-simple mmodule.
+java_test {
+ name: "core-simple-mmodule-test",
+ srcs: [ "src/test/java/**/*.java" ],
+ no_framework_libs: true,
+
+ no_standard_libs: true,
+ libs: [
+ // We depend on stubs not the impl code. We do not test mmodule
+ // internals, just the {public SDK API + intra-core mmodule API}.
+ "core-all.mmodule.stubs",
+ // Other deps needed for tests.
+ "junit",
+ ],
+ system_modules: "core-all-mmodule-stubs-system-modules",
+}
+
+// Generates stub source files for the {public SDK API + intra-core mmodule API}
+// of the core-simple mmodule.
+droiddoc {
+ name: "core-simple-mmodule-stubs-docs",
+ srcs: [":core_simple_mmodule_java_files"],
+ installable: false,
+ no_framework_libs: true,
+ metalava_enabled: true,
+ args: "-nodocs -stubsourceonly -showAnnotation libcore.mmodule.IntraCoreMModuleApi",
+}
+
+// A library containing the {public SDK API + intra-core mmodule API} stubs for
+// the core-simple mmodule.
+java_library {
+ name: "core-simple.mmodule.stubs",
+ srcs: [
+ ":core-simple-mmodule-stubs-docs",
+ ],
+
+ no_framework_libs: true,
+
+ no_standard_libs: true,
+ // We use core-all.mmodule.stubs here to prove that we have all the
+ // dependencies needed to compile the mmodule stubs within the stubs, i.e.
+ // there are no non-API references.
+ libs: ["core-all.mmodule.stubs"],
+ system_modules: "core-all-mmodule-stubs-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
+
+java_system_modules {
+ name: "core-all-mmodule-stubs-system-modules",
+ libs: ["core-all.mmodule.stubs"],
+}
+
diff --git a/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java b/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java
new file mode 100644
index 0000000..413746909
--- /dev/null
+++ b/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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 libcore.mmodule.simple;
+
+import libcore.mmodule.IntraCoreMModuleApi;
+import libcore.mmodule.DemoLibartClass;
+
+/**
+ * A class that nothing in libcore or the Android framework depends on to provide public SDK
+ * behavior. It is intended for use in a fake installable mmodule. Its presence can be tested for,
+ * the classloader identified and its behavior modified over time to simulate real mmodule code,
+ * without touching any "real" platform logic.
+ *
+ * @hide
+ */
+@IntraCoreMModuleApi
+public class DemoSimpleClass {
+
+ private DemoSimpleClass() {}
+
+ /**
+ * A simple method that has no native or data file dependencies but is part of the simple
+ * mmodule's API contract.
+ *
+ * @hide
+ */
+ @IntraCoreMModuleApi
+ public static String simpleMethod() {
+ return "Hello World";
+ }
+
+ /**
+ * A method that depends on another part of the core libraries to work.
+ *
+ * @hide
+ */
+ @IntraCoreMModuleApi // Exposed for tests
+ public static String intraCoreDependencyMethod() {
+ // Delegate to core-libart code to implement the method.
+ return DemoLibartClass.simpleMethod();
+ }
+
+ /**
+ * A method that is public but not part of the simple mmodule's API contract.
+ *
+ * @hide
+ */
+ public static String hiddenMethod() {
+ return "Hello World";
+ }
+}
diff --git a/modules/simple/src/test/java/libcore/test/simple/TestClassTest.java b/mmodules/simple/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
similarity index 65%
copy from modules/simple/src/test/java/libcore/test/simple/TestClassTest.java
copy to mmodules/simple/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
index acdea98..f383390 100644
--- a/modules/simple/src/test/java/libcore/test/simple/TestClassTest.java
+++ b/mmodules/simple/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
@@ -14,32 +14,36 @@
* limitations under the License.
*/
-package libcore.test.simple;
+package libcore.test.mmodule.libart;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
-
-import libcore.simple.TestClass;
+import libcore.mmodule.DemoLibartClass;
import org.junit.Test;
/**
- * A test for the presence and behavior of {@link TestClass}.
+ * A test for the presence and behavior of {@link DemoLibartClass}.
*/
-public class TestClassTest {
+public class DemoLibartClassTest {
@Test
public void classLoader() {
- Class<?> clazz = TestClass.class;
+ Class<?> clazz = DemoLibartClass.class;
ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
- // The TestClass must be loaded by the boot classloader.
+ // The DemoLibartClass must be loaded by the boot classloader.
assertSame(bootClassLoader, clazz.getClassLoader());
}
@Test
public void simpleMethod() {
- assertEquals("Hello World", TestClass.simpleMethod());
+ assertEquals("Hello World", DemoLibartClass.simpleMethod());
+ }
+
+ @Test
+ public void intraCoreDependencyMethod() {
+ assertEquals("Hello World", DemoLibartClass.intraCoreDependencyMethod());
}
}
diff --git a/modules/simple/src/test/java/libcore/test/simple/TestClassTest.java b/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
similarity index 65%
rename from modules/simple/src/test/java/libcore/test/simple/TestClassTest.java
rename to mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
index acdea98..523eed5 100644
--- a/modules/simple/src/test/java/libcore/test/simple/TestClassTest.java
+++ b/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
@@ -14,32 +14,36 @@
* limitations under the License.
*/
-package libcore.test.simple;
+package libcore.test.mmodule.simple;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
-
-import libcore.simple.TestClass;
+import libcore.mmodule.simple.DemoSimpleClass;
import org.junit.Test;
/**
- * A test for the presence and behavior of {@link TestClass}.
+ * A test for the presence and behavior of {@link DemoSimpleClass}.
*/
-public class TestClassTest {
+public class DemoSimpleClassTest {
@Test
public void classLoader() {
- Class<?> clazz = TestClass.class;
+ Class<?> clazz = DemoSimpleClass.class;
ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
- // The TestClass must be loaded by the boot classloader.
+ // The DemoSimpleClass must be loaded by the boot classloader.
assertSame(bootClassLoader, clazz.getClassLoader());
}
@Test
public void simpleMethod() {
- assertEquals("Hello World", TestClass.simpleMethod());
+ assertEquals("Hello World", DemoSimpleClass.simpleMethod());
+ }
+
+ @Test
+ public void intraCoreDependencyMethod() {
+ assertEquals("Hello World", DemoSimpleClass.intraCoreDependencyMethod());
}
}
diff --git a/modules/simple/Android.bp b/modules/simple/Android.bp
deleted file mode 100644
index f9e7a28..0000000
--- a/modules/simple/Android.bp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// 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.
-
-java_defaults {
- name: "core-simple-defaults",
- srcs: [ "src/main/java/**/*.java" ],
- installable: true,
- no_standard_libs: true,
- no_framework_libs: true,
- libs: [
- "core-oj",
- "core-libart",
- ],
- system_modules: "core-all-system-modules",
- dxflags: ["--core-library"],
-}
-
-java_library {
- name: "core-simple",
- hostdex: true,
- defaults: ["core-simple-defaults"],
-}
-
-// A guaranteed unstripped version of core-simple.
-// The build system may or may not strip the core-simple jar
-// but this will not be stripped. See b/24535627.
-java_library {
- name: "core-simple-testdex",
- defaults: ["core-simple-defaults"],
- dex_preopt: {
- enabled: false,
- },
-}
-
-java_test {
- name: "core-simple-test",
- srcs: [ "src/test/java/**/*.java" ],
- libs: [
- "core-simple",
- "junit",
- ],
- no_framework_libs: true,
-}
diff --git a/modules/simple/src/main/java/libcore/simple/TestClass.java b/modules/simple/src/main/java/libcore/simple/TestClass.java
deleted file mode 100644
index eebb569..0000000
--- a/modules/simple/src/main/java/libcore/simple/TestClass.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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 libcore.simple;
-
-/**
- * A class that nothing in libcore or the Android framework depends on. It is intended for use in a
- * fake installable module. Its presence can be tested for, the classloader identified and its
- * behavior modified over time to simulate a real module, without touching any "real" platform
- * logic.
- */
-public class TestClass {
-
- private TestClass() {}
-
- /**
- * A simple method that has no native or data file dependencies.
- */
- public static String simpleMethod() {
- return "Hello World";
- }
-}
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 0b3af9d..523babb 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -156,6 +156,8 @@
"luni/src/main/java/javax/xml/xpath/XPathFunctionException.java",
"luni/src/main/java/javax/xml/xpath/XPathFunctionResolver.java",
"luni/src/main/java/javax/xml/xpath/XPathVariableResolver.java",
+ "luni/src/main/java/libcore/mmodule/DemoLibartClass.java",
+ "luni/src/main/java/libcore/mmodule/IntraCoreMModuleApi.java",
"json/src/main/java/org/json/JSON.java",
"json/src/main/java/org/json/JSONArray.java",
"json/src/main/java/org/json/JSONException.java",