This is an automated email from the ASF dual-hosted git repository.
slfan1989 pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git
The following commit(s) were added to refs/heads/trunk by this push:
new df9e73822e1 HADOOP-19402. [JDK11] JDiff Support JDK11. (#8038)
Contributed by Hualong Zhang.
df9e73822e1 is described below
commit df9e73822e1e2c299a25401fc1576c681954ab91
Author: hualong <[email protected]>
AuthorDate: Mon Dec 29 22:33:25 2025 +0800
HADOOP-19402. [JDK11] JDiff Support JDK11. (#8038) Contributed by Hualong
Zhang.
* HADOOP-19402. [JDK11] JDiff Support JDK11.
Reviewed-by: Chris Nauroth <[email protected]>
Signed-off-by: Shilun Fan <[email protected]>
---
hadoop-common-project/hadoop-annotations/pom.xml | 56 +---
.../ExcludePrivateAnnotationsJDiffDoclet.java | 59 +++-
.../ExcludePrivateAnnotationsStandardDoclet.java | 203 ++++++++++++
.../tools/IncludePublicAnnotationsJDiffDoclet.java | 198 +++++++++++
.../IncludePublicAnnotationsStandardDoclet.java | 198 +++++++++++
.../classification/tools/RootDocProcessor.java | 369 +++++++++++++++++++++
.../classification/tools/StabilityOptions.java | 100 +++++-
.../ExcludePrivateAnnotationsStandardDoclet.java | 62 ----
.../tools/IncludePublicAnnotationsJDiffDoclet.java | 64 ----
.../IncludePublicAnnotationsStandardDoclet.java | 63 ----
.../classification/tools/RootDocProcessor.java | 251 --------------
.../hadoop-mapreduce-client/pom.xml | 2 +-
hadoop-project-dist/pom.xml | 27 +-
hadoop-project/pom.xml | 4 +-
hadoop-yarn-project/hadoop-yarn/pom.xml | 2 +-
15 files changed, 1144 insertions(+), 514 deletions(-)
diff --git a/hadoop-common-project/hadoop-annotations/pom.xml
b/hadoop-common-project/hadoop-annotations/pom.xml
index bc7a2ef60b6..86bc5d92379 100644
--- a/hadoop-common-project/hadoop-annotations/pom.xml
+++ b/hadoop-common-project/hadoop-annotations/pom.xml
@@ -31,50 +31,24 @@
<dependencies>
<dependency>
- <groupId>jdiff</groupId>
+ <groupId>io.github.zhtttylz</groupId>
<artifactId>jdiff</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
- <profiles>
- <profile>
- <id>jdk1.8</id>
- <activation>
- <jdk>1.8</jdk>
- </activation>
- <dependencies>
- <dependency>
- <groupId>jdk.tools</groupId>
- <artifactId>jdk.tools</artifactId>
- <version>1.8</version>
- <scope>system</scope>
- <systemPath>${java.home}/../lib/tools.jar</systemPath>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${basedir}/src/main/java8</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <compilerArgs>
+ <arg>--add-modules</arg>
+ <arg>jdk.javadoc</arg>
+ </compilerArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java
similarity index 56%
rename from
hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java
rename to
hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java
index 5cc422f5893..ab55d758edb 100644
---
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java
+++
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java
@@ -17,31 +17,55 @@
*/
package org.apache.hadoop.classification.tools;
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+import javax.lang.model.SourceVersion;
import jdiff.JDiff;
/**
- * A <a
href="http://java.sun.com/javase/6/docs/jdk/api/javadoc/doclet/">Doclet</a>
- * for excluding elements that are annotated with
+ * <a href=
+ *
"https://docs.oracle.com/en/java/javase/17/docs/api/jdk.javadoc/jdk/javadoc/doclet/Doclet.html">
+ * Doclet</a> for excluding elements that are annotated with
* {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
* {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}.
* It delegates to the JDiff Doclet, and takes the same options.
*/
-public class ExcludePrivateAnnotationsJDiffDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
+public final class ExcludePrivateAnnotationsJDiffDoclet {
+
+ /**
+ * Returns the source version used by this doclet.
+ *
+ * @return the supported source version
+ */
+ public static SourceVersion languageVersion() {
+ return SourceVersion.RELEASE_17;
}
-
- public static boolean start(RootDoc root) {
+
+ /**
+ * Legacy doclet entry point used by JDiff/Javadoc.
+ *
+ * @param root the doclet environment
+ * @return true if the doclet completed successfully
+ */
+ public static boolean start(DocletEnvironment root) {
System.out.println(
ExcludePrivateAnnotationsJDiffDoclet.class.getSimpleName());
return JDiff.start(RootDocProcessor.process(root));
}
-
+
+ /**
+ * Utility class: provides only static entry points for JDiff.
+ */
+ private ExcludePrivateAnnotationsJDiffDoclet() {
+ }
+
+ /**
+ * Returns the length of a supported option.
+ *
+ * @param option the option name
+ * @return the number of arguments including the option itself
+ */
public static int optionLength(String option) {
Integer length = StabilityOptions.optionLength(option);
if (length != null) {
@@ -49,9 +73,16 @@ public static int optionLength(String option) {
}
return JDiff.optionLength(option);
}
-
+
+ /**
+ * Validates options before running the doclet.
+ *
+ * @param options the options to validate
+ * @param reporter the reporter to use for diagnostics
+ * @return true if the options are valid
+ */
public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
+ Reporter reporter) {
StabilityOptions.validOptions(options, reporter);
String[][] filteredOptions = StabilityOptions.filterOptions(options);
return JDiff.validOptions(filteredOptions, reporter);
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
new file mode 100644
index 00000000000..31fa2fd7c79
--- /dev/null
+++
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.classification.tools;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.StandardDoclet;
+
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * <a href=
+ *
"https://docs.oracle.com/en/java/javase/17/docs/api/jdk.javadoc/jdk/javadoc/doclet/Doclet.html">
+ * Doclet</a> for excluding elements that are
+ * annotated with {@link
org.apache.hadoop.classification.InterfaceAudience.Private}
+ * or {@link
org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}.
+ * It delegates to the Standard Doclet, and takes the same options.
+ */
+public class ExcludePrivateAnnotationsStandardDoclet implements Doclet {
+
+ private final StandardDoclet delegate = new StandardDoclet();
+ private Reporter reporter;
+ private Locale locale;
+
+ /**
+ * Public no-arg constructor required by the Javadoc tool.
+ */
+ public ExcludePrivateAnnotationsStandardDoclet() {
+ }
+
+ /**
+ * Returns the source version used by this doclet.
+ *
+ * @return the supported source version
+ */
+ public static SourceVersion languageVersion() {
+ return SourceVersion.RELEASE_17;
+ }
+
+ /**
+ * Legacy doclet entry point used by Javadoc.
+ *
+ * @param root the doclet environment
+ * @return true if the doclet completed successfully
+ */
+ public static boolean start(DocletEnvironment root) {
+
System.out.println(ExcludePrivateAnnotationsStandardDoclet.class.getSimpleName());
+ if (root.getSpecifiedElements().isEmpty()) {
+ return true;
+ }
+ return new StandardDoclet().run(root);
+ }
+
+ /**
+ * Returns the length of a supported option.
+ *
+ * @param option the option name
+ * @return the number of arguments including the option itself
+ */
+ public static int optionLength(String option) {
+ Integer length = StabilityOptions.optionLength(option);
+ if (length != null) {
+ return length;
+ }
+ for (Doclet.Option o : new StandardDoclet().getSupportedOptions()) {
+ for (String name : o.getNames()) {
+ if (name.equals(option)) {
+ return o.getArgumentCount() + 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Validates options before running the doclet.
+ *
+ * @param options the options to validate
+ * @param reporter the reporter to use for diagnostics
+ * @return true if the options are valid
+ */
+ public static boolean validOptions(String[][] options, Reporter reporter) {
+ StabilityOptions.validOptions(options, reporter);
+ return true;
+ }
+
+ @Override
+ public void init(Locale initLocale, Reporter initReporter) {
+ this.locale = initLocale;
+ this.reporter = initReporter;
+ delegate.init(locale, reporter);
+ }
+
+ @Override
+ public String getName() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public Set<Option> getSupportedOptions() {
+ Set<Option> s = new java.util.HashSet<>(delegate.getSupportedOptions());
+ s.add(new Option() {
+ @Override
+ public int getArgumentCount() {
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.OTHER;
+ }
+
+ @Override
+ public java.util.List<String> getNames() {
+ return java.util.Collections.singletonList("-unstable");
+ }
+
+ @Override
+ public String getParameters() {
+ return "";
+ }
+
+ @Override
+ public boolean process(String opt, java.util.List<String> args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.UNSTABLE);
+ return true;
+ }
+ });
+ s.add(new Option() {
+ @Override
+ public int getArgumentCount() {
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.OTHER;
+ }
+
+ @Override
+ public java.util.List<String> getNames() {
+ return java.util.Collections.singletonList("-evolving");
+ }
+
+ @Override
+ public String getParameters() {
+ return "";
+ }
+
+ @Override
+ public boolean process(String opt, java.util.List<String> args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.EVOLVING);
+ return true;
+ }
+ });
+ return s;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.RELEASE_17;
+ }
+
+ @Override
+ public boolean run(DocletEnvironment environment) {
+ StabilityOptions.applyToRootProcessor();
+ RootDocProcessor.process(environment);
+
+ if (environment.getIncludedElements().isEmpty()) {
+ return true;
+ }
+ return delegate.run(environment);
+ }
+}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
new file mode 100644
index 00000000000..374519336a2
--- /dev/null
+++
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.classification.tools;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import javax.lang.model.SourceVersion;
+
+import jdiff.JDiff;
+
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * <a href=
+ *
"https://docs.oracle.com/en/java/javase/17/docs/api/jdk.javadoc/jdk/javadoc/doclet/Doclet.html">
+ * Doclet</a> that only includes class-level elements that are annotated
+ * with {@link org.apache.hadoop.classification.InterfaceAudience.Public}.
+ * Class-level elements with no annotation are excluded.
+ * In addition, all elements that are annotated with
+ * {@link org.apache.hadoop.classification.InterfaceAudience.Private}
+ * or {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}
+ * are also excluded.
+ * It delegates to the JDiff Doclet, and takes the same options.
+ */
+public class IncludePublicAnnotationsJDiffDoclet implements Doclet {
+
+ private final JDiff delegate = new JDiff();
+ private Reporter reporter;
+ private Locale locale;
+
+ @Override
+ public void init(Locale newLocale, Reporter newReporter) {
+ this.locale = newLocale;
+ this.reporter = newReporter;
+ delegate.init(newLocale, newReporter);
+ }
+
+ @Override
+ public String getName() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public Set<Option> getSupportedOptions() {
+ Set<Option> s = new java.util.HashSet<>(delegate.getSupportedOptions());
+ s.add(new Option() {
+ @Override
+ public int getArgumentCount() {
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.OTHER;
+ }
+
+ @Override
+ public java.util.List<String> getNames() {
+ return java.util.Collections.singletonList("-unstable");
+ }
+
+ @Override
+ public String getParameters() {
+ return "";
+ }
+
+ @Override
+ public boolean process(String opt, java.util.List<String> args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.UNSTABLE);
+ return true;
+ }
+ });
+ s.add(new Option() {
+ @Override
+ public int getArgumentCount() {
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.OTHER;
+ }
+
+ @Override
+ public java.util.List<String> getNames() {
+ return java.util.Collections.singletonList("-evolving");
+ }
+
+ @Override
+ public String getParameters() {
+ return "";
+ }
+
+ @Override
+ public boolean process(String opt, java.util.List<String> args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.EVOLVING);
+ return true;
+ }
+ });
+ return s;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.RELEASE_17;
+ }
+
+ @Override
+ public boolean run(DocletEnvironment root) {
+
System.out.println(IncludePublicAnnotationsJDiffDoclet.class.getSimpleName());
+ RootDocProcessor.setTreatUnannotatedClassesAsPrivate(true);
+ StabilityOptions.applyToRootProcessor();
+ return delegate.run(RootDocProcessor.process(root));
+ }
+
+ /**
+ * Returns the source version used by this doclet.
+ *
+ * @return the supported source version
+ */
+ public static SourceVersion languageVersion() {
+ return SourceVersion.RELEASE_17;
+ }
+
+ /**
+ * Public no-arg constructor required by the Javadoc tool.
+ */
+ public IncludePublicAnnotationsJDiffDoclet() {
+ }
+
+ /**
+ * Legacy doclet entry point used by JDiff/Javadoc.
+ *
+ * @param root the doclet environment
+ * @return true if the doclet completed successfully
+ */
+ public static boolean start(DocletEnvironment root) {
+ System.out.println(
+ IncludePublicAnnotationsJDiffDoclet.class.getSimpleName());
+ RootDocProcessor.setTreatUnannotatedClassesAsPrivate(true);
+ return JDiff.start(RootDocProcessor.process(root));
+ }
+
+ /**
+ * Returns the length of a supported option.
+ *
+ * @param option the option name
+ * @return the number of arguments including the option itself
+ */
+ public static int optionLength(String option) {
+ Integer length = StabilityOptions.optionLength(option);
+ if (length != null) {
+ return length;
+ }
+ return JDiff.optionLength(option);
+ }
+
+ /**
+ * Validates options before running the doclet.
+ *
+ * @param options the options to validate
+ * @param reporter the reporter to use for diagnostics
+ * @return true if the options are valid
+ */
+ public static boolean validOptions(String[][] options, Reporter reporter) {
+ StabilityOptions.validOptions(options, reporter);
+ String[][] filteredOptions = StabilityOptions.filterOptions(options);
+ return JDiff.validOptions(filteredOptions, reporter);
+ }
+}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
new file mode 100644
index 00000000000..634a99b57fc
--- /dev/null
+++
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.classification.tools;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.StandardDoclet;
+
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * <a href=
+ *
"https://docs.oracle.com/en/java/javase/17/docs/api/jdk.javadoc/jdk/javadoc/doclet/Doclet.html">
+ * Doclet</a> that only includes class-level elements that are annotated
+ * with {@link org.apache.hadoop.classification.InterfaceAudience.Public}.
+ * Class-level elements with no annotation are excluded.
+ * In addition, all elements that are annotated with
+ * {@link org.apache.hadoop.classification.InterfaceAudience.Private}
+ * or {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}
+ * are also excluded.
+ * It delegates to the Standard Doclet, and takes the same options.
+ */
+public class IncludePublicAnnotationsStandardDoclet implements Doclet {
+
+ /**
+ * Returns the source version used by this doclet.
+ *
+ * @return the supported source version
+ */
+ public static SourceVersion languageVersion() {
+ return SourceVersion.RELEASE_17;
+ }
+
+ /**
+ * Public no-arg constructor required by the Javadoc tool.
+ */
+ public IncludePublicAnnotationsStandardDoclet() {
+ }
+
+ private final StandardDoclet delegate = new StandardDoclet();
+
+ @Override
+ public void init(Locale locale, Reporter reporter) {
+ delegate.init(locale, reporter);
+ }
+
+ @Override
+ public String getName() {
+ return IncludePublicAnnotationsStandardDoclet.class.getSimpleName();
+ }
+
+ @Override
+ public Set<Option> getSupportedOptions() {
+ Set<Option> s = new java.util.HashSet<>(delegate.getSupportedOptions());
+ s.add(new Option() {
+ @Override
+ public int getArgumentCount() {
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.OTHER;
+ }
+
+ @Override
+ public java.util.List<String> getNames() {
+ return java.util.Collections.singletonList("-unstable");
+ }
+
+ @Override
+ public String getParameters() {
+ return "";
+ }
+
+ @Override
+ public boolean process(String opt, java.util.List<String> args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.UNSTABLE);
+ return true;
+ }
+ });
+ s.add(new Option() {
+ @Override
+ public int getArgumentCount() {
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.OTHER;
+ }
+
+ @Override
+ public java.util.List<String> getNames() {
+ return java.util.Collections.singletonList("-evolving");
+ }
+
+ @Override
+ public String getParameters() {
+ return "";
+ }
+
+ @Override
+ public boolean process(String opt, java.util.List<String> args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.UNSTABLE);
+ return true;
+ }
+ });
+ return s;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return delegate.getSupportedSourceVersion();
+ }
+
+ @Override
+ public boolean run(DocletEnvironment env) {
+ System.out.println(getName());
+ RootDocProcessor.setTreatUnannotatedClassesAsPrivate(true);
+ StabilityOptions.applyToRootProcessor();
+ DocletEnvironment filtered = RootDocProcessor.process(env);
+ return delegate.run(filtered);
+ }
+
+ /**
+ * Legacy doclet entry point used by Javadoc.
+ *
+ * @param env the doclet environment
+ * @return true if the doclet completed successfully
+ */
+ public static boolean start(DocletEnvironment env) {
+ return new IncludePublicAnnotationsStandardDoclet().run(env);
+ }
+
+ /**
+ * Returns the length of a supported option.
+ *
+ * @param option the option name
+ * @return the number of arguments including the option itself
+ */
+ public static int optionLength(String option) {
+ Integer length = StabilityOptions.optionLength(option);
+ if (length != null) {
+ return length;
+ }
+ for (jdk.javadoc.doclet.Doclet.Option o :
+ new StandardDoclet().getSupportedOptions()) {
+ for (String name : o.getNames()) {
+ if (name.equals(option)) {
+ return o.getArgumentCount() + 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Validates options before running the doclet.
+ *
+ * @param options the options to validate
+ * @param reporter the reporter to use for diagnostics
+ * @return true if the options are valid
+ */
+ public static boolean validOptions(String[][] options, Reporter reporter) {
+ StabilityOptions.validOptions(options, reporter);
+ return true;
+ }
+}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java
new file mode 100644
index 00000000000..741a1c7d068
--- /dev/null
+++
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.classification.tools;
+
+import jdk.javadoc.doclet.DocletEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.stream.Collectors;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Process the {@link DocletEnvironment} by substituting with (nested) proxy
objects that
+ * exclude elements with Private or LimitedPrivate annotations.
+ * <p>
+ * Based on code from
http://www.sixlegs.com/blog/java/exclude-javadoc-tag.html.
+ */
+final class RootDocProcessor {
+
+ private static String stability = StabilityOptions.UNSTABLE_OPTION;
+ private static boolean treatUnannotatedClassesAsPrivate = false;
+
+ static void setStability(String value) {
+ stability = value;
+ }
+
+ private RootDocProcessor() {
+ // no instances
+ }
+
+
+ static String getStability() {
+ return stability;
+ }
+
+ static void setTreatUnannotatedClassesAsPrivate(boolean value) {
+ treatUnannotatedClassesAsPrivate = value;
+ }
+
+ static boolean isTreatUnannotatedClassesAsPrivate() {
+ return treatUnannotatedClassesAsPrivate;
+ }
+
+ public static DocletEnvironment process(DocletEnvironment root) {
+ return (DocletEnvironment) wrap(root, DocletEnvironment.class);
+ }
+
+ private static final Map<Object, Object> PROXIES = new WeakHashMap<>();
+
+ private static Object wrap(Object obj, Class<?> expectedType) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (obj instanceof DocletEnvironment) {
+ return getProxy(obj, new Class<?>[]{DocletEnvironment.class},
+ new EnvHandler((DocletEnvironment) obj));
+ }
+
+ if (obj instanceof Element) {
+ return getElementProxy((Element) obj);
+ }
+
+ if (obj instanceof Set) {
+ return filterAndWrapIterable((Iterable<?>) obj, true);
+ }
+ if (obj instanceof Collection) {
+ return filterAndWrapIterable((Iterable<?>) obj, false);
+ }
+ if (obj instanceof Iterable) {
+ return filterAndWrapIterable((Iterable<?>) obj, false);
+ }
+
+ if (obj.getClass().isArray()) {
+ int len = Array.getLength(obj);
+ Object[] res = new Object[len];
+ for (int i = 0; i < len; i++) {
+ Object v = Array.get(obj, i);
+ res[i] = wrap(v, v != null ? v.getClass() : Object.class);
+ }
+ return res;
+ }
+
+ return obj;
+ }
+
+ private static Object getElementProxy(Element el) {
+ Object cached = PROXIES.get(el);
+ if (cached != null) {
+ return cached;
+ }
+
+ Set<Class<?>> ifaces = new LinkedHashSet<>();
+ Collections.addAll(ifaces, el.getClass().getInterfaces());
+ ifaces.add(Element.class);
+ if (el instanceof TypeElement) {
+ ifaces.add(TypeElement.class);
+ }
+ if (el instanceof PackageElement) {
+ ifaces.add(PackageElement.class);
+ }
+ if (el instanceof ExecutableElement) {
+ ifaces.add(ExecutableElement.class);
+ }
+ if (el instanceof VariableElement) {
+ ifaces.add(VariableElement.class);
+ }
+
+ Object proxy = getProxy(el, ifaces.toArray(new Class<?>[0]), new
ElementHandler(el));
+ PROXIES.put(el, proxy);
+ return proxy;
+ }
+
+ private static Object getProxy(Object target, Class<?>[] ifaces,
InvocationHandler h) {
+ Object cached = PROXIES.get(target);
+ if (cached != null) {
+ return cached;
+ }
+ Object p = Proxy.newProxyInstance(target.getClass().getClassLoader(),
ifaces, h);
+ PROXIES.put(target, p);
+ return p;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Object filterAndWrapIterable(Iterable<?> iterable, boolean
preserveSet) {
+ if (iterable == null) {
+ return null;
+ }
+ if (preserveSet) {
+ Set<Object> out = new LinkedHashSet<>();
+ for (Object o : iterable) {
+ if (o instanceof Element) {
+ Element el = (Element) o;
+ if (!exclude(el)) {
+ out.add(getElementProxy(el));
+ }
+ } else {
+ out.add(wrap(o, o != null ? o.getClass() : Object.class));
+ }
+ }
+ return out;
+ } else {
+ List<Object> out = new ArrayList<>();
+ for (Object o : iterable) {
+ if (o instanceof Element) {
+ Element el = (Element) o;
+ if (!exclude(el)) {
+ out.add(getElementProxy(el));
+ }
+ } else {
+ out.add(wrap(o, o != null ? o.getClass() : Object.class));
+ }
+ }
+ return out;
+ }
+ }
+
+ private static Object unwrap(Object maybeProxy) {
+ if (!(maybeProxy instanceof Proxy)) {
+ return maybeProxy;
+ }
+ InvocationHandler ih = Proxy.getInvocationHandler(maybeProxy);
+ if (ih instanceof BaseHandler) {
+ return ((BaseHandler) ih).target;
+ }
+ return maybeProxy;
+ }
+
+ private static boolean exclude(Element el) {
+ boolean sawPublic = false;
+
+ for (AnnotationMirror am : el.getAnnotationMirrors()) {
+ final String qname = am.getAnnotationType().toString();
+
+ if (qname.equals(InterfaceAudience.Private.class.getCanonicalName())
+ ||
qname.equals(InterfaceAudience.LimitedPrivate.class.getCanonicalName())) {
+ return true;
+ }
+
+ if (stability.equals(StabilityOptions.EVOLVING_OPTION)) {
+ if
(qname.equals(InterfaceStability.Unstable.class.getCanonicalName())) {
+ return true;
+ }
+ }
+ if (stability.equals(StabilityOptions.STABLE_OPTION)) {
+ if (qname.equals(InterfaceStability.Unstable.class.getCanonicalName())
+ ||
qname.equals(InterfaceStability.Evolving.class.getCanonicalName())) {
+ return true;
+ }
+ }
+
+ if (qname.equals(InterfaceAudience.Public.class.getCanonicalName())) {
+ sawPublic = true;
+ }
+ }
+
+ if (sawPublic) {
+ return false;
+ }
+
+ if (isTreatUnannotatedClassesAsPrivate()) {
+ ElementKind k = el.getKind();
+ if (k == ElementKind.CLASS || k == ElementKind.INTERFACE ||
+ k == ElementKind.ANNOTATION_TYPE) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static abstract class BaseHandler implements InvocationHandler {
+ private final Object target;
+
+ BaseHandler(Object target) {
+ this.target = target;
+ }
+
+ protected Object getTarget() {
+ return target;
+ }
+
+ Object wrapReturn(Object ret) {
+ if (ret == null) {
+ return null;
+ }
+ if (ret instanceof DocletEnvironment) {
+ return wrap(ret, DocletEnvironment.class);
+ }
+ if (ret instanceof Element) {
+ return getElementProxy((Element) ret);
+ }
+ if (ret instanceof Set) {
+ return filterAndWrapIterable((Set<?>) ret, true);
+ }
+ if (ret instanceof Collection) {
+ return filterAndWrapIterable((Collection<?>) ret, false);
+ }
+ if (ret instanceof Iterable) {
+ return filterAndWrapIterable((Iterable<?>) ret, false);
+ }
+ if (ret.getClass().isArray()) {
+ return wrap(ret, ret.getClass());
+ }
+ return ret;
+ }
+
+ Object[] unwrapArgs(Object[] args) {
+ if (args == null) {
+ return null;
+ }
+ Object[] r = new Object[args.length];
+ for (int i = 0; i < args.length; i++) {
+ r[i] = unwrap(args[i]);
+ }
+ return r;
+ }
+ }
+
+ private static final class EnvHandler extends BaseHandler {
+ private final DocletEnvironment env;
+
+ EnvHandler(DocletEnvironment env) {
+ super(env);
+ this.env = env;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
+ String name = method.getName();
+ Object[] uargs = unwrapArgs(args);
+
+ if ("getDocTrees".equals(name)) {
+ return env.getDocTrees();
+ } else if ("isIncluded".equals(name)) {
+ Element e = (Element) uargs[0];
+ boolean base = env.isIncluded(e);
+ return base && !exclude(e);
+ } else if ("getIncludedElements".equals(name)) {
+ Set<? extends Element> base = env.getIncludedElements();
+ return base.stream()
+ .filter(e -> !exclude(e))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ } else if ("getSpecifiedElements".equals(name)) {
+ Set<? extends Element> base = env.getSpecifiedElements();
+ return base.stream()
+ .filter(e -> !exclude(e))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
+ Object ret = method.invoke(getTarget(), uargs);
+ return wrapReturn(ret);
+ }
+ }
+
+ private static final class ElementHandler extends BaseHandler {
+ private final Element element;
+
+ ElementHandler(Element element) {
+ super(element);
+ this.element = element;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
+ String name = method.getName();
+ Object[] uargs = unwrapArgs(args);
+
+ if ("equals".equals(name) && uargs != null && uargs.length == 1) {
+ return Objects.equals(element, unwrap(uargs[0]));
+ }
+ if ("hashCode".equals(name) && (uargs == null || uargs.length == 0)) {
+ return element.hashCode();
+ }
+ if ("toString".equals(name) && (uargs == null || uargs.length == 0)) {
+ return element.toString();
+ }
+
+ if ("getEnclosedElements".equals(name) && (uargs == null || uargs.length
== 0)) {
+ List<? extends Element> enclosed = element.getEnclosedElements();
+ List<Element> filtered = new ArrayList<>();
+ for (Element e : enclosed) {
+ if (!exclude(e)) {
+ filtered.add(e);
+ }
+ }
+ return filtered;
+ }
+
+ Object ret = method.invoke(getTarget(), uargs);
+ return wrapReturn(ret);
+ }
+ }
+}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/StabilityOptions.java
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/StabilityOptions.java
similarity index 50%
rename from
hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/StabilityOptions.java
rename to
hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/StabilityOptions.java
index 5b2d70ded3f..c9d23ab472b 100644
---
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/StabilityOptions.java
+++
b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/StabilityOptions.java
@@ -17,39 +17,111 @@
*/
package org.apache.hadoop.classification.tools;
-import com.sun.javadoc.DocErrorReporter;
+import jdk.javadoc.doclet.Reporter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-class StabilityOptions {
+/**
+ * Doclet option helpers for API stability filtering.
+ */
+public final class StabilityOptions {
+
+ /** Option flag: {@code -stable}. */
public static final String STABLE_OPTION = "-stable";
+
+ /** Option flag: {@code -evolving}. */
public static final String EVOLVING_OPTION = "-evolving";
+
+ /** Option flag: {@code -unstable}. */
public static final String UNSTABLE_OPTION = "-unstable";
+ enum Level { STABLE, EVOLVING, UNSTABLE }
+ private static volatile Level level = Level.STABLE;
+
+ static void setLevel(Level l) {
+ if (l != null) {
+ level = l;
+ }
+ }
+
+ private StabilityOptions() {
+ }
+
+ /**
+ * Return option length for a supported stability option.
+ *
+ * @param option option name
+ * @return {@code 1} if supported; otherwise {@code null}
+ */
public static Integer optionLength(String option) {
String opt = option.toLowerCase(Locale.ENGLISH);
- if (opt.equals(UNSTABLE_OPTION)) return 1;
- if (opt.equals(EVOLVING_OPTION)) return 1;
- if (opt.equals(STABLE_OPTION)) return 1;
+ if (opt.equals(UNSTABLE_OPTION)) {
+ return 1;
+ }
+ if (opt.equals(EVOLVING_OPTION)) {
+ return 1;
+ }
+ if (opt.equals(STABLE_OPTION)) {
+ return 1;
+ }
return null;
}
+ static void setFromOptionName(String optName) {
+ String opt = optName.toLowerCase(Locale.ENGLISH);
+ Level next = null;
+ if (opt.equals(UNSTABLE_OPTION)) {
+ next = Level.UNSTABLE;
+ } else if (opt.equals(EVOLVING_OPTION)) {
+ next = Level.EVOLVING;
+ } else if (opt.equals(STABLE_OPTION)) {
+ next = Level.STABLE;
+ }
+ if (next != null && next.ordinal() > level.ordinal()) {
+ level = next;
+ }
+ }
+
+ static Level getLevel() {
+ return level;
+ }
+
+ static void applyToRootProcessor() {
+ switch (level) {
+ case UNSTABLE:
+ RootDocProcessor.setStability(UNSTABLE_OPTION);
+ break;
+ case EVOLVING:
+ RootDocProcessor.setStability(EVOLVING_OPTION);
+ break;
+ default:
+ RootDocProcessor.setStability(STABLE_OPTION);
+ }
+ }
+
+ /**
+ * Validate and apply stability options.
+ *
+ * @param options doclet options
+ * @param reporter reporter
+ */
public static void validOptions(String[][] options,
- DocErrorReporter reporter) {
+ Reporter reporter) {
for (int i = 0; i < options.length; i++) {
String opt = options[i][0].toLowerCase(Locale.ENGLISH);
- if (opt.equals(UNSTABLE_OPTION)) {
- RootDocProcessor.stability = UNSTABLE_OPTION;
- } else if (opt.equals(EVOLVING_OPTION)) {
- RootDocProcessor.stability = EVOLVING_OPTION;
- } else if (opt.equals(STABLE_OPTION)) {
- RootDocProcessor.stability = STABLE_OPTION;
- }
+ setFromOptionName(opt);
}
+ applyToRootProcessor();
}
-
+
+ /**
+ * Filter out stability options from the doclet options array.
+ *
+ * @param options doclet options
+ * @return options without stability flags
+ */
public static String[][] filterOptions(String[][] options) {
List<String[]> optionsList = new ArrayList<String[]>();
for (int i = 0; i < options.length; i++) {
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
deleted file mode 100644
index 5c535c8e9e3..00000000000
---
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
-import com.sun.tools.doclets.standard.Standard;
-
-/**
- * A <a
href="http://java.sun.com/javase/6/docs/jdk/api/javadoc/doclet/">Doclet</a>
- * for excluding elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
- * {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}.
- * It delegates to the Standard Doclet, and takes the same options.
- */
-public class ExcludePrivateAnnotationsStandardDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
- }
-
- public static boolean start(RootDoc root) {
- System.out.println(
- ExcludePrivateAnnotationsStandardDoclet.class.getSimpleName());
- RootDoc excludedDoc = RootDocProcessor.process(root);
- if (excludedDoc.specifiedPackages().length == 0) {
- return true;
- }
- return Standard.start(excludedDoc);
- }
-
- public static int optionLength(String option) {
- Integer length = StabilityOptions.optionLength(option);
- if (length != null) {
- return length;
- }
- return Standard.optionLength(option);
- }
-
- public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
- StabilityOptions.validOptions(options, reporter);
- String[][] filteredOptions = StabilityOptions.filterOptions(options);
- return Standard.validOptions(filteredOptions, reporter);
- }
-}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
deleted file mode 100644
index 91b3a9ddf25..00000000000
---
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
-
-import jdiff.JDiff;
-
-/**
- * A <a
href="http://java.sun.com/javase/6/docs/jdk/api/javadoc/doclet/">Doclet</a>
- * that only includes class-level elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Public}.
- * Class-level elements with no annotation are excluded.
- * In addition, all elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
- * {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}
- * are also excluded.
- * It delegates to the JDiff Doclet, and takes the same options.
- */
-public class IncludePublicAnnotationsJDiffDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
- }
-
- public static boolean start(RootDoc root) {
- System.out.println(
- IncludePublicAnnotationsJDiffDoclet.class.getSimpleName());
- RootDocProcessor.treatUnannotatedClassesAsPrivate = true;
- return JDiff.start(RootDocProcessor.process(root));
- }
-
- public static int optionLength(String option) {
- Integer length = StabilityOptions.optionLength(option);
- if (length != null) {
- return length;
- }
- return JDiff.optionLength(option);
- }
-
- public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
- StabilityOptions.validOptions(options, reporter);
- String[][] filteredOptions = StabilityOptions.filterOptions(options);
- return JDiff.validOptions(filteredOptions, reporter);
- }
-}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
deleted file mode 100644
index 10d554d07b5..00000000000
---
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
-import com.sun.tools.doclets.standard.Standard;
-
-/**
- * A <a
href="http://java.sun.com/javase/6/docs/jdk/api/javadoc/doclet/">Doclet</a>
- * that only includes class-level elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Public}.
- * Class-level elements with no annotation are excluded.
- * In addition, all elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
- * {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}
- * are also excluded.
- * It delegates to the Standard Doclet, and takes the same options.
- */
-public class IncludePublicAnnotationsStandardDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
- }
-
- public static boolean start(RootDoc root) {
- System.out.println(
- IncludePublicAnnotationsStandardDoclet.class.getSimpleName());
- RootDocProcessor.treatUnannotatedClassesAsPrivate = true;
- return Standard.start(RootDocProcessor.process(root));
- }
-
- public static int optionLength(String option) {
- Integer length = StabilityOptions.optionLength(option);
- if (length != null) {
- return length;
- }
- return Standard.optionLength(option);
- }
-
- public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
- StabilityOptions.validOptions(options, reporter);
- String[][] filteredOptions = StabilityOptions.filterOptions(options);
- return Standard.validOptions(filteredOptions, reporter);
- }
-}
diff --git
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/RootDocProcessor.java
b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/RootDocProcessor.java
deleted file mode 100644
index 60c2a6f6e93..00000000000
---
a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/RootDocProcessor.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.AnnotationDesc;
-import com.sun.javadoc.AnnotationTypeDoc;
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.ConstructorDoc;
-import com.sun.javadoc.Doc;
-import com.sun.javadoc.FieldDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.PackageDoc;
-import com.sun.javadoc.ProgramElementDoc;
-import com.sun.javadoc.RootDoc;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-
-/**
- * Process the {@link RootDoc} by substituting with (nested) proxy objects that
- * exclude elements with Private or LimitedPrivate annotations.
- * <p>
- * Based on code from
http://www.sixlegs.com/blog/java/exclude-javadoc-tag.html.
- */
-class RootDocProcessor {
-
- static String stability = StabilityOptions.UNSTABLE_OPTION;
- static boolean treatUnannotatedClassesAsPrivate = false;
-
- public static RootDoc process(RootDoc root) {
- return (RootDoc) process(root, RootDoc.class);
- }
-
- private static Object process(Object obj, Class<?> type) {
- if (obj == null) {
- return null;
- }
- Class<?> cls = obj.getClass();
- if (cls.getName().startsWith("com.sun.")) {
- return getProxy(obj);
- } else if (obj instanceof Object[]) {
- Class<?> componentType = type.isArray() ? type.getComponentType()
- : cls.getComponentType();
- Object[] array = (Object[]) obj;
- Object[] newArray = (Object[]) Array.newInstance(componentType,
- array.length);
- for (int i = 0; i < array.length; ++i) {
- newArray[i] = process(array[i], componentType);
- }
- return newArray;
- }
- return obj;
- }
-
- private static Map<Object, Object> proxies =
- new WeakHashMap<Object, Object>();
-
- private static Object getProxy(Object obj) {
- Object proxy = proxies.get(obj);
- if (proxy == null) {
- proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(),
- obj.getClass().getInterfaces(), new ExcludeHandler(obj));
- proxies.put(obj, proxy);
- }
- return proxy;
- }
-
- private static class ExcludeHandler implements InvocationHandler {
- private Object target;
-
- public ExcludeHandler(Object target) {
- this.target = target;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- String methodName = method.getName();
- if (target instanceof Doc) {
- if (methodName.equals("isIncluded")) {
- Doc doc = (Doc) target;
- return !exclude(doc) && doc.isIncluded();
- }
- if (target instanceof RootDoc) {
- if (methodName.equals("classes")) {
- return filter(((RootDoc) target).classes(), ClassDoc.class);
- } else if (methodName.equals("specifiedClasses")) {
- return filter(((RootDoc) target).specifiedClasses(),
ClassDoc.class);
- } else if (methodName.equals("specifiedPackages")) {
- return filter(((RootDoc) target).specifiedPackages(),
PackageDoc.class);
- }
- } else if (target instanceof ClassDoc) {
- if (isFiltered(args)) {
- if (methodName.equals("methods")) {
- return filter(((ClassDoc) target).methods(true),
MethodDoc.class);
- } else if (methodName.equals("fields")) {
- return filter(((ClassDoc) target).fields(true), FieldDoc.class);
- } else if (methodName.equals("innerClasses")) {
- return filter(((ClassDoc) target).innerClasses(true),
- ClassDoc.class);
- } else if (methodName.equals("constructors")) {
- return filter(((ClassDoc) target).constructors(true),
- ConstructorDoc.class);
- }
- } else {
- if (methodName.equals("methods")) {
- return filter(((ClassDoc) target).methods(true),
MethodDoc.class);
- }
- }
- } else if (target instanceof PackageDoc) {
- if (methodName.equals("allClasses")) {
- if (isFiltered(args)) {
- return filter(((PackageDoc) target).allClasses(true),
- ClassDoc.class);
- } else {
- return filter(((PackageDoc) target).allClasses(),
ClassDoc.class);
- }
- } else if (methodName.equals("annotationTypes")) {
- return filter(((PackageDoc) target).annotationTypes(),
- AnnotationTypeDoc.class);
- } else if (methodName.equals("enums")) {
- return filter(((PackageDoc) target).enums(),
- ClassDoc.class);
- } else if (methodName.equals("errors")) {
- return filter(((PackageDoc) target).errors(),
- ClassDoc.class);
- } else if (methodName.equals("exceptions")) {
- return filter(((PackageDoc) target).exceptions(),
- ClassDoc.class);
- } else if (methodName.equals("interfaces")) {
- return filter(((PackageDoc) target).interfaces(),
- ClassDoc.class);
- } else if (methodName.equals("ordinaryClasses")) {
- return filter(((PackageDoc) target).ordinaryClasses(),
- ClassDoc.class);
- }
- }
- }
-
- if (args != null) {
- if (methodName.equals("compareTo") || methodName.equals("equals")
- || methodName.equals("overrides")
- || methodName.equals("subclassOf")) {
- args[0] = unwrap(args[0]);
- }
- }
- try {
- return process(method.invoke(target, args), method.getReturnType());
- } catch (InvocationTargetException e) {
- throw e.getTargetException();
- }
- }
-
- private static boolean exclude(Doc doc) {
- AnnotationDesc[] annotations = null;
- if (doc instanceof ProgramElementDoc) {
- annotations = ((ProgramElementDoc) doc).annotations();
- } else if (doc instanceof PackageDoc) {
- annotations = ((PackageDoc) doc).annotations();
- }
- if (annotations != null) {
- for (AnnotationDesc annotation : annotations) {
- String qualifiedTypeName =
annotation.annotationType().qualifiedTypeName();
- if (qualifiedTypeName.equals(
- InterfaceAudience.Private.class.getCanonicalName())
- || qualifiedTypeName.equals(
- InterfaceAudience.LimitedPrivate.class.getCanonicalName())) {
- return true;
- }
- if (stability.equals(StabilityOptions.EVOLVING_OPTION)) {
- if (qualifiedTypeName.equals(
- InterfaceStability.Unstable.class.getCanonicalName())) {
- return true;
- }
- }
- if (stability.equals(StabilityOptions.STABLE_OPTION)) {
- if (qualifiedTypeName.equals(
- InterfaceStability.Unstable.class.getCanonicalName())
- || qualifiedTypeName.equals(
- InterfaceStability.Evolving.class.getCanonicalName())) {
- return true;
- }
- }
- }
- for (AnnotationDesc annotation : annotations) {
- String qualifiedTypeName =
- annotation.annotationType().qualifiedTypeName();
- if (qualifiedTypeName.equals(
- InterfaceAudience.Public.class.getCanonicalName())) {
- return false;
- }
- }
- }
- if (treatUnannotatedClassesAsPrivate) {
- return doc.isClass() || doc.isInterface() || doc.isAnnotationType();
- }
- return false;
- }
-
- private static Object[] filter(Doc[] array, Class<?> componentType) {
- if (array == null || array.length == 0) {
- return array;
- }
- List<Object> list = new ArrayList<Object>(array.length);
- for (Doc entry : array) {
- if (!exclude(entry)) {
- list.add(process(entry, componentType));
- }
- }
- return list.toArray((Object[]) Array.newInstance(componentType, list
- .size()));
- }
-
- private Object unwrap(Object proxy) {
- if (proxy instanceof Proxy)
- return ((ExcludeHandler) Proxy.getInvocationHandler(proxy)).target;
- return proxy;
- }
-
- private boolean isFiltered(Object[] args) {
- return args != null && Boolean.TRUE.equals(args[0]);
- }
-
- }
-
-}
diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
b/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
index f236c8770d3..f8c7ad3d4b9 100644
--- a/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
+++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
@@ -246,7 +246,7 @@
<configuration>
<artifactItems>
<artifactItem>
- <groupId>jdiff</groupId>
+ <groupId>io.github.zhtttylz</groupId>
<artifactId>jdiff</artifactId>
<version>${jdiff.version}</version>
<overWrite>false</overWrite>
diff --git a/hadoop-project-dist/pom.xml b/hadoop-project-dist/pom.xml
index 68d29e84fbf..f09a22f23c5 100644
--- a/hadoop-project-dist/pom.xml
+++ b/hadoop-project-dist/pom.xml
@@ -178,7 +178,7 @@
<configuration>
<artifactItems>
<artifactItem>
- <groupId>jdiff</groupId>
+ <groupId>io.github.zhtttylz</groupId>
<artifactId>jdiff</artifactId>
<version>${jdiff.version}</version>
<overWrite>false</overWrite>
@@ -462,5 +462,30 @@
</plugins>
</build>
</profile>
+ <profile>
+ <id>doclet-jdk17</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+
<doclet>org.apache.hadoop.classification.tools.ExcludePrivateAnnotationsStandardDoclet</doclet>
+ <docletArtifacts>
+ <docletArtifact>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-annotations</artifactId>
+ <version>${hadoop.version}</version>
+ </docletArtifact>
+ </docletArtifacts>
+ <useStandardDocletOptions>true</useStandardDocletOptions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
</profiles>
</project>
diff --git a/hadoop-project/pom.xml b/hadoop-project/pom.xml
index cd83d2ae9a9..5d07b0228d5 100644
--- a/hadoop-project/pom.xml
+++ b/hadoop-project/pom.xml
@@ -45,7 +45,7 @@
<!-- These 2 versions are defined here because they are used -->
<!-- JDIFF generation from embedded ant in the antrun plugin -->
- <jdiff.version>1.0.9</jdiff.version>
+ <jdiff.version>1.1.2-hadoop</jdiff.version>
<!-- Version number for xerces used by JDiff -->
<xerces.jdiff.version>2.12.2</xerces.jdiff.version>
@@ -268,7 +268,7 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>jdiff</groupId>
+ <groupId>io.github.zhtttylz</groupId>
<artifactId>jdiff</artifactId>
<version>${jdiff.version}</version>
</dependency>
diff --git a/hadoop-yarn-project/hadoop-yarn/pom.xml
b/hadoop-yarn-project/hadoop-yarn/pom.xml
index db4a50542fd..7c216f90043 100644
--- a/hadoop-yarn-project/hadoop-yarn/pom.xml
+++ b/hadoop-yarn-project/hadoop-yarn/pom.xml
@@ -151,7 +151,7 @@
<configuration>
<artifactItems>
<artifactItem>
- <groupId>jdiff</groupId>
+ <groupId>io.github.zhtttylz</groupId>
<artifactId>jdiff</artifactId>
<version>${jdiff.version}</version>
<overWrite>false</overWrite>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]