undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Class to have a missing annotation applied for running MissingTest.
*/
@Missing
@Marker
public class A {
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Class to have an indirectly missing annotation applied for
* running MisssingTest.
*/
@MissingWrapper(@Missing)
@Marker
public class B {
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Class to have a missing annotation applied for running MissingTest.
*/
public class C {
public void method1(@Missing @Marker Object param1) {
return;
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Class to have a missing annotation applied for running MissingTest.
*/
public class D {
public void method1(@MissingWrapper(@Missing) @Marker Object param1) {
return;
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*;
/**
* A marker annotation. Used so that at least one annotation will be
* present on the classes tested by MissingTest.
*/
@Retention(RUNTIME)
public @interface Marker {}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*;
/**
* The class file for this annotation type is missing when MissingTest
* is run.
*/
@Retention(RUNTIME)
public @interface Missing {}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The enum that will be seen at compile-time.
*
* <p>The filename deliberately does not match, since we need to declare two versions of the enum
* for compile-time and runtime.
*/
enum Enum {
ONE,
TWO,
THREE
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The enum that will be seen at runtime.
*
* <p>The filename deliberately does not match, since we need to declare two versions of the enum
* for compile-time and runtime.
*/
enum Enum {
ONE
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
/** An annotation that will be missing at runtime. */
@Retention(RUNTIME)
public @interface MissingAnnotation {}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/*
* @test
* @bug 7183985
* @summary getAnnotation() should throw NoClassDefFoundError when an annotation class is not
* present at runtime
* @compile MissingAnnotationArrayElementTest.java MissingAnnotation.java
* @clean MissingAnnotation
* @run main MissingAnnotationArrayElementTest
*/
public class MissingAnnotationArrayElementTest {
@Retention(RUNTIME)
@interface AnnotationAnnotation {
MissingAnnotation[] value();
}
@AnnotationAnnotation({@MissingAnnotation, @MissingAnnotation})
static class Test {
void f(@AnnotationAnnotation({@MissingAnnotation, @MissingAnnotation}) int x) {}
Test(@AnnotationAnnotation({@MissingAnnotation, @MissingAnnotation}) int x) {}
}
public static void main(String[] args) throws Exception {
// MissingAnnotation will be absent from the runtime classpath, causing a
// NoClassDefFoundError when AnnotationAnnotation is read (since the type of its value array
// references cannot be completed).
assertThrowsNoClassDefFoundError(
() -> Test.class.getAnnotation(AnnotationAnnotation.class));
Method method = Test.class.getDeclaredMethod("f", int.class);
assertThrowsNoClassDefFoundError(method::getParameterAnnotations);
Constructor constructor = Test.class.getDeclaredConstructor(int.class);
assertThrowsNoClassDefFoundError(constructor::getParameterAnnotations);
}
interface ThrowingRunnable {
void run() throws Exception;
}
static void assertThrowsNoClassDefFoundError(ThrowingRunnable throwingRunnable)
throws Exception {
try {
throwingRunnable.run();
throw new AssertionError("expected exception");
} catch (NoClassDefFoundError expected) {
if (!expected.getMessage().contains("MissingAnnotation")) {
throw expected;
}
}
}
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/** A class that will be missing at runtime. */
public class MissingClass {}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/** A class that will be missing at runtime. */
public class MissingClass2 {}

View file

@ -0,0 +1,147 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.util.Arrays;
/*
* @test
* @bug 7183985
* @summary getAnnotation() throws an ArrayStoreException when the annotation class not present
* @compile MissingClassArrayElementTest.java MissingClass.java MissingClass2.java
* @clean MissingClass MissingClass2
* @run main MissingClassArrayElementTest
*/
public class MissingClassArrayElementTest {
@Retention(RUNTIME)
@interface AnnotationAnnotation {
ClassArrayAnnotation[] value();
}
@Retention(RUNTIME)
@interface ClassArrayAnnotation {
Class<?>[] value();
}
@AnnotationAnnotation({
@ClassArrayAnnotation({MissingClass.class}),
@ClassArrayAnnotation({MissingClass.class, String.class}),
@ClassArrayAnnotation({String.class, MissingClass.class}),
@ClassArrayAnnotation({MissingClass.class, MissingClass2.class}),
@ClassArrayAnnotation({String.class})
})
static class Test {
void f(
@AnnotationAnnotation({
@ClassArrayAnnotation({MissingClass.class, MissingClass.class}),
@ClassArrayAnnotation({Float.class})
})
int x,
@AnnotationAnnotation({@ClassArrayAnnotation({Double.class})}) int y) {}
Test(
@AnnotationAnnotation({
@ClassArrayAnnotation({MissingClass.class, MissingClass.class}),
@ClassArrayAnnotation({Short.class}),
})
int x,
@AnnotationAnnotation({@ClassArrayAnnotation({Character.class})}) int y) {}
}
public static void main(String[] args) throws Exception {
classAnnotationTest();
methodParameterAnnotationsTest();
constructorParameterAnnotationsTest();
}
static void classAnnotationTest() throws Exception {
ClassArrayAnnotation[] outer = Test.class.getAnnotation(AnnotationAnnotation.class).value();
assertMissing(outer[0]);
assertMissing(outer[1]);
assertMissing(outer[2]);
assertMissing(outer[3]);
assertArrayEquals(outer[4].value(), new Class<?>[] {String.class});
}
static void methodParameterAnnotationsTest() throws Exception {
AnnotationAnnotation[] methodParameterAnnotations =
Arrays.stream(
Test.class
.getDeclaredMethod("f", int.class, int.class)
.getParameterAnnotations())
.map(x -> ((AnnotationAnnotation) x[0]))
.toArray(AnnotationAnnotation[]::new);
// The first parameter's annotation contains some well-formed values, and the second
// parameter's
// annotation is well-formed
assertArrayEquals(
methodParameterAnnotations[0].value()[1].value(), new Class<?>[] {Float.class});
assertArrayEquals(
methodParameterAnnotations[1].value()[0].value(), new Class<?>[] {Double.class});
// The first parameter's annotation contains a missing value
assertMissing(methodParameterAnnotations[0].value()[0]);
}
static void constructorParameterAnnotationsTest() throws Exception {
AnnotationAnnotation[] constructorParameterAnnotations =
Arrays.stream(
Test.class
.getDeclaredConstructor(int.class, int.class)
.getParameterAnnotations())
.map(x -> ((AnnotationAnnotation) x[0]))
.toArray(AnnotationAnnotation[]::new);
// The first parameter's annotation contains some well-formed values, and the second
// parameter's
// annotation is well-formed
assertArrayEquals(
constructorParameterAnnotations[0].value()[1].value(),
new Class<?>[] {Short.class});
assertArrayEquals(
constructorParameterAnnotations[1].value()[0].value(),
new Class<?>[] {Character.class});
// The first parameter's annotation contains a missing value
assertMissing(constructorParameterAnnotations[0].value()[0]);
}
static void assertArrayEquals(Object[] actual, Object[] expected) {
if (!Arrays.equals(actual, expected)) {
throw new AssertionError(
"expected: " + Arrays.toString(expected) + ", was: " + Arrays.toString(actual));
}
}
static void assertMissing(ClassArrayAnnotation missing) {
try {
missing.value();
throw new AssertionError("expected exception");
} catch (TypeNotPresentException expected) {
if (!expected.typeName().equals("MissingClass")) {
throw new AssertionError(
"expected TypeNotPresentException: MissingClass", expected);
}
}
}
}

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2018, Google Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.util.Arrays;
/*
* @test
* @bug 7183985
* @summary getAnnotation() throws an ArrayStoreException when the annotation class not present
* @compile MissingEnumArrayElementTest.java EnumToCompileAgainst.java
* @clean Enum
* @compile EnumToRunAgainst.java
* @run main MissingEnumArrayElementTest
*/
public class MissingEnumArrayElementTest {
@Retention(RUNTIME)
@interface AnnotationAnnotation {
EnumArrayAnnotation[] value();
}
@Retention(RUNTIME)
@interface EnumArrayAnnotation {
Enum[] value();
}
@AnnotationAnnotation({
@EnumArrayAnnotation({Enum.TWO}),
@EnumArrayAnnotation({Enum.ONE, Enum.TWO}),
@EnumArrayAnnotation({Enum.TWO, Enum.ONE}),
@EnumArrayAnnotation({Enum.TWO, Enum.THREE}),
@EnumArrayAnnotation({Enum.ONE}),
})
static class Test {
void f(
@AnnotationAnnotation({
@EnumArrayAnnotation({Enum.TWO, Enum.ONE}),
@EnumArrayAnnotation({Enum.ONE})
})
int x,
@AnnotationAnnotation({@EnumArrayAnnotation({Enum.ONE})}) int y) {}
Test(
@AnnotationAnnotation({
@EnumArrayAnnotation({Enum.TWO, Enum.ONE}),
@EnumArrayAnnotation({Enum.ONE})
})
int x,
@AnnotationAnnotation({@EnumArrayAnnotation({Enum.ONE})}) int y) {}
}
public static void main(String[] args) throws Exception {
classAnnotationTest();
methodParameterAnnotationsTest();
constructorParameterAnnotationsTest();
}
static void classAnnotationTest() throws Exception {
EnumArrayAnnotation[] outer = Test.class.getAnnotation(AnnotationAnnotation.class).value();
assertMissing(outer[0]);
assertMissing(outer[1]);
assertMissing(outer[2]);
assertMissing(outer[3]);
assertArrayEquals(outer[4].value(), new Enum[] {Enum.ONE});
}
static void methodParameterAnnotationsTest() throws Exception {
AnnotationAnnotation[] methodParameterAnnotations =
Arrays.stream(
Test.class
.getDeclaredMethod("f", int.class, int.class)
.getParameterAnnotations())
.map(x -> ((AnnotationAnnotation) x[0]))
.toArray(AnnotationAnnotation[]::new);
// The first parameter's annotation contains some well-formed values, and the second
// parameter's
// annotation is well-formed
assertArrayEquals(methodParameterAnnotations[0].value()[1].value(), new Enum[] {Enum.ONE});
assertArrayEquals(methodParameterAnnotations[1].value()[0].value(), new Enum[] {Enum.ONE});
// The first parameter's annotation contains a missing value
assertMissing(methodParameterAnnotations[0].value()[0]);
}
static void constructorParameterAnnotationsTest() throws Exception {
AnnotationAnnotation[] constructorParameterAnnotations =
Arrays.stream(
Test.class
.getDeclaredConstructor(int.class, int.class)
.getParameterAnnotations())
.map(x -> ((AnnotationAnnotation) x[0]))
.toArray(AnnotationAnnotation[]::new);
// The first parameter's annotation contains some well-formed values, and the second
// parameter's
// annotation is well-formed
assertArrayEquals(constructorParameterAnnotations[0].value()[1].value(), new Enum[] {Enum.ONE});
assertArrayEquals(constructorParameterAnnotations[1].value()[0].value(), new Enum[] {Enum.ONE});
// The first parameter's annotation contains a missing value
assertMissing(constructorParameterAnnotations[0].value()[0]);
}
static void assertArrayEquals(Object[] actual, Object[] expected) {
if (!Arrays.equals(actual, expected)) {
throw new AssertionError(
"expected: " + Arrays.toString(expected) + ", was: " + Arrays.toString(actual));
}
}
static void assertMissing(EnumArrayAnnotation annotation) throws Exception {
try {
annotation.value();
throw new AssertionError("expected exception");
} catch (EnumConstantNotPresentException expected) {
if (!expected.getMessage().equals("Enum.TWO")) {
throw new AssertionError(
"expected EnumConstantNotPresentException for Enum.TWO", expected);
}
}
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Annotation type with a default value whose class will be missing
* when MissingTest is run.
*/
@Retention(RUNTIME)
public @interface MissingDefault {
Class<?> value() default Missing.class;
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6322301 5041778
* @summary Verify when missing annotation classes cause exceptions
* @compile MissingTest.java A.java B.java C.java D.java Marker.java Missing.java MissingWrapper.java MissingDefault.java
* @clean Missing
* @run main MissingTest
*/
import java.lang.reflect.*;
import java.lang.annotation.*;
/**
* This test verifies that a missing annotation class leads to the
* expected exceptional behavior; a missing directly applied
* annotation is currently ignored but a missing annotation value
* inside another annotation throws an exception.
*
* To be run as intended, the annotation type Missing should *not* be
* on the classpath when the test is run; with jtreg, it is deleted by
* the @clean directive.
*/
public class MissingTest {
/**
* For the annotated element argument, get all its annotations and
* see whether or not an exception is throw upon reading the
* annotations. Additionally, verify at least one annotation is
* present.
*/
private static void testAnnotation(AnnotatedElement element,
boolean exceptionExpected) {
java.lang.annotation.Annotation[] annotations;
try {
annotations = element.getAnnotations();
if (exceptionExpected) {
System.err.println("Error: Did not get an exception reading annotations on "
+ element);
System.err.println("Annotations found: "
+ java.util.Arrays.toString(annotations));
throw new RuntimeException();
}
if (annotations.length == 0) {
System.err.println("Error: no annotations found on " + element);
throw new RuntimeException();
}
} catch (Throwable t) {
if (!exceptionExpected) {
System.err.println("Error: Got an unexpected exception reading annotations on "
+ element);
throw new RuntimeException(t);
}
}
}
/**
* For the annotated element argument, get all its annotations and
* see whether or not an exception is throw upon reading the
* annotations. Additionally, verify at least one annotation is
* present.
*/
private static void testParameterAnnotation(Method m,
boolean exceptionExpected) {
java.lang.annotation.Annotation[][] annotationsArray;
try {
annotationsArray = m.getParameterAnnotations();
if (exceptionExpected) {
System.err.println("Error: Did not get an exception reading annotations on method"
+ m);
System.err.println("Annotations found: "
+ java.util.Arrays.toString(annotationsArray));
throw new RuntimeException();
}
if (annotationsArray.length == 0 ) {
System.err.println("Error: no parameters for " + m);
throw new RuntimeException();
} else {
java.lang.annotation.Annotation[] annotations = annotationsArray[0];
if (annotations.length == 0) {
System.err.println("Error: no annotations on " + m);
throw new RuntimeException();
}
}
} catch (Throwable t) {
if (!exceptionExpected) {
System.err.println("Error: Got an unexpected exception reading annotations on "
+ m);
throw new RuntimeException(t);
}
}
}
private static void testMethodGetDefaultValue(Class<?> clazz) throws Exception{
Method m = clazz.getMethod("value", (Class<?>[])null);
try {
System.out.println(m.getDefaultValue());
throw new RuntimeException("Expected exception not thrown");
} catch (TypeNotPresentException tnpe) {
; // Expected
} catch (AnnotationFormatError afe) {
throw new RuntimeException(afe);
}
}
public static void main(String... args) throws Exception {
// Class A has a directly applied annotation whose class is
// missing.
testAnnotation(A.class, false);
// Class B has a directly applied annotation whose value
// includes to an annotation class that is missing.
testAnnotation(B.class, true);
// Class C has a directly applied parameter annotation whose
// class is missing.
testParameterAnnotation(C.class.getDeclaredMethod("method1", Object.class),
false);
// Class D has a directly applied parameter annotation whose value
// includes to an annotation class that is missing.
testParameterAnnotation(D.class.getDeclaredMethod("method1", Object.class),
true);
// The MissingDefault annotation type has a default value of the Missing class.
testMethodGetDefaultValue(MissingDefault.class);
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Annotation wrapper around an annotation whose class will be missing
* when MissingTest is run.
*/
@Retention(RUNTIME)
public @interface MissingWrapper {
Missing value();
}