This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git


The following commit(s) were added to refs/heads/master by this push:
     new 8485c2d0 Add JavaClassCyclicTest
8485c2d0 is described below

commit 8485c2d04bf7b43528ac87121d73afe14b29383f
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Jan 9 13:56:21 2026 -0500

    Add JavaClassCyclicTest
---
 .../java/org/apache/bcel/classfile/JavaClass.java  |   9 +
 .../java/org/apache/bcel/Java8PublicClasses.java   | 989 +++++++++++++++++++++
 .../apache/bcel/classfile/JavaClassCyclicTest.java | 161 ++++
 .../org/apache/bcel/classfile/JavaClassTest.java   | 328 +------
 4 files changed, 1191 insertions(+), 296 deletions(-)

diff --git a/src/main/java/org/apache/bcel/classfile/JavaClass.java 
b/src/main/java/org/apache/bcel/classfile/JavaClass.java
index 648ef21b..0bd51408 100644
--- a/src/main/java/org/apache/bcel/classfile/JavaClass.java
+++ b/src/main/java/org/apache/bcel/classfile/JavaClass.java
@@ -467,9 +467,13 @@ public class JavaClass extends AccessFlags implements 
Cloneable, Node, Comparabl
     public JavaClass[] getAllInterfaces() throws ClassNotFoundException {
         final ClassQueue queue = new ClassQueue();
         final Set<JavaClass> allInterfaces = new TreeSet<>();
+        final Set<JavaClass> visited = new HashSet<>();
         queue.enqueue(this);
         while (!queue.empty()) {
             final JavaClass clazz = queue.dequeue();
+            if (!visited.add(clazz)) {
+                continue;
+            }
             final JavaClass souper = clazz.getSuperClass();
             final JavaClass[] interfaces = clazz.getInterfaces();
             if (clazz.isInterface()) {
@@ -693,7 +697,12 @@ public class JavaClass extends AccessFlags implements 
Cloneable, Node, Comparabl
     public JavaClass[] getSuperClasses() throws ClassNotFoundException {
         JavaClass clazz = this;
         final List<JavaClass> allSuperClasses = new ArrayList<>();
+        final Set<JavaClass> visited = new HashSet<>();
+        visited.add(this);
         for (clazz = clazz.getSuperClass(); clazz != null; clazz = 
clazz.getSuperClass()) {
+            if (!visited.add(clazz)) {
+                throw new ClassCircularityError(clazz.getClassName());
+            }
             allSuperClasses.add(clazz);
         }
         return allSuperClasses.toArray(EMPTY_ARRAY);
diff --git a/src/test/java/org/apache/bcel/Java8PublicClasses.java 
b/src/test/java/org/apache/bcel/Java8PublicClasses.java
new file mode 100644
index 00000000..2dd48d7b
--- /dev/null
+++ b/src/test/java/org/apache/bcel/Java8PublicClasses.java
@@ -0,0 +1,989 @@
+/*
+ * 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
+ *
+ *   https://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.bcel;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.CharConversionException;
+import java.io.Closeable;
+import java.io.Console;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.Externalizable;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.FilterWriter;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.InterruptedIOException;
+import java.io.InvalidClassException;
+import java.io.InvalidObjectException;
+import java.io.LineNumberReader;
+import java.io.NotActiveException;
+import java.io.NotSerializableException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectInputValidation;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+import java.io.OptionalDataException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.PushbackInputStream;
+import java.io.PushbackReader;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.io.SequenceInputStream;
+import java.io.Serializable;
+import java.io.SerializablePermission;
+import java.io.StreamCorruptedException;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.SyncFailedException;
+import java.io.UTFDataFormatException;
+import java.io.UncheckedIOException;
+import java.io.UnsupportedEncodingException;
+import java.io.WriteAbortedException;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.annotation.AnnotationTypeMismatchException;
+import java.lang.annotation.Documented;
+import java.lang.annotation.IncompleteAnnotationException;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Native;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.SwitchPoint;
+import java.lang.invoke.VolatileCallSite;
+import java.lang.invoke.WrongMethodTypeException;
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedArrayType;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.AnnotatedTypeVariable;
+import java.lang.reflect.AnnotatedWildcardType;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.MalformedParameterizedTypeException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.ReflectPermission;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.lang.reflect.WildcardType;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.net.Authenticator;
+import java.net.BindException;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ConnectException;
+import java.net.ContentHandler;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.CookieStore;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+import java.net.FileNameMap;
+import java.net.HttpCookie;
+import java.net.HttpRetryException;
+import java.net.HttpURLConnection;
+import java.net.IDN;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.InterfaceAddress;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.MulticastSocket;
+import java.net.NetPermission;
+import java.net.NetworkInterface;
+import java.net.NoRouteToHostException;
+import java.net.PasswordAuthentication;
+import java.net.PortUnreachableException;
+import java.net.ProtocolException;
+import java.net.ProxySelector;
+import java.net.ResponseCache;
+import java.net.SecureCacheResponse;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketOption;
+import java.net.SocketOptions;
+import java.net.SocketPermission;
+import java.net.SocketTimeoutException;
+import java.net.StandardProtocolFamily;
+import java.net.StandardSocketOptions;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.net.URLStreamHandler;
+import java.net.UnknownHostException;
+import java.net.UnknownServiceException;
+import java.nio.Buffer;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.InvalidMarkException;
+import java.nio.LongBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.nio.ShortBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnmappableCharacterException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.AtomicMoveNotSupportedException;
+import java.nio.file.ClosedDirectoryStreamException;
+import java.nio.file.ClosedFileSystemException;
+import java.nio.file.ClosedWatchServiceException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryNotEmptyException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystemException;
+import java.nio.file.FileSystemLoopException;
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.NotDirectoryException;
+import java.nio.file.NotLinkException;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.ProviderNotFoundException;
+import java.nio.file.ReadOnlyFileSystemException;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.nio.file.Watchable;
+import java.nio.file.attribute.AclEntry;
+import java.nio.file.attribute.AclEntryFlag;
+import java.nio.file.attribute.AclEntryPermission;
+import java.nio.file.attribute.AclEntryType;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.AttributeView;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.DosFileAttributeView;
+import java.nio.file.attribute.DosFileAttributes;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileOwnerAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.GroupPrincipal;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.nio.file.attribute.UserDefinedFileAttributeView;
+import java.nio.file.attribute.UserPrincipal;
+import java.nio.file.attribute.UserPrincipalLookupService;
+import java.nio.file.attribute.UserPrincipalNotFoundException;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.AlgorithmParametersSpi;
+import java.security.AllPermission;
+import java.security.AuthProvider;
+import java.security.BasicPermission;
+import java.security.Certificate;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.DigestException;
+import java.security.DigestInputStream;
+import java.security.DigestOutputStream;
+import java.security.DomainCombiner;
+import java.security.GeneralSecurityException;
+import java.security.Guard;
+import java.security.GuardedObject;
+import java.security.Identity;
+import java.security.IdentityScope;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.KeyException;
+import java.security.KeyFactory;
+import java.security.KeyFactorySpi;
+import java.security.KeyManagementException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyPairGeneratorSpi;
+import java.security.KeyRep;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.MessageDigest;
+import java.security.MessageDigestSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.PolicySpi;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.security.Provider;
+import java.security.ProviderException;
+import java.security.PublicKey;
+import java.security.SecureClassLoader;
+import java.security.SecureRandom;
+import java.security.SecureRandomSpi;
+import java.security.Security;
+import java.security.SecurityPermission;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.SignedObject;
+import java.security.Signer;
+import java.security.UnrecoverableEntryException;
+import java.security.UnrecoverableKeyException;
+import java.security.UnresolvedPermission;
+import java.sql.BatchUpdateException;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DataTruncation;
+import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLData;
+import java.sql.SQLDataException;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLInput;
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.sql.SQLInvalidAuthorizationSpecException;
+import java.sql.SQLNonTransientConnectionException;
+import java.sql.SQLNonTransientException;
+import java.sql.SQLOutput;
+import java.sql.SQLPermission;
+import java.sql.SQLRecoverableException;
+import java.sql.SQLSyntaxErrorException;
+import java.sql.SQLTimeoutException;
+import java.sql.SQLTransactionRollbackException;
+import java.sql.SQLTransientConnectionException;
+import java.sql.SQLTransientException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.sql.Wrapper;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.Bidi;
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+import java.text.ChoiceFormat;
+import java.text.CollationElementIterator;
+import java.text.CollationKey;
+import java.text.Collator;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.MessageFormat;
+import java.text.Normalizer;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.text.RuleBasedCollator;
+import java.text.SimpleDateFormat;
+import java.text.StringCharacterIterator;
+import java.time.Clock;
+import java.time.DateTimeException;
+import java.time.DayOfWeek;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Month;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.chrono.AbstractChronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoPeriod;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.Era;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.HijrahEra;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.IsoEra;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.JapaneseEra;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.MinguoDate;
+import java.time.chrono.MinguoEra;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ThaiBuddhistDate;
+import java.time.chrono.ThaiBuddhistEra;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
+import java.time.format.DecimalStyle;
+import java.time.format.FormatStyle;
+import java.time.format.ResolverStyle;
+import java.time.format.SignStyle;
+import java.time.format.TextStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.IsoFields;
+import java.time.temporal.JulianFields;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAdjusters;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQueries;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+import java.time.temporal.ValueRange;
+import java.time.temporal.WeekFields;
+import java.time.zone.ZoneOffsetTransition;
+import java.time.zone.ZoneOffsetTransitionRule;
+import java.time.zone.ZoneRules;
+import java.time.zone.ZoneRulesException;
+import java.time.zone.ZoneRulesProvider;
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.AbstractMap;
+import java.util.AbstractQueue;
+import java.util.AbstractSequentialList;
+import java.util.AbstractSet;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.BitSet;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Currency;
+import java.util.Date;
+import java.util.Deque;
+import java.util.Dictionary;
+import java.util.DoubleSummaryStatistics;
+import java.util.DuplicateFormatFlagsException;
+import java.util.EmptyStackException;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.EventListenerProxy;
+import java.util.EventObject;
+import java.util.FormatFlagsConversionMismatchException;
+import java.util.Formattable;
+import java.util.FormattableFlags;
+import java.util.Formatter;
+import java.util.FormatterClosedException;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.IllegalFormatCodePointException;
+import java.util.IllegalFormatConversionException;
+import java.util.IllegalFormatException;
+import java.util.IllegalFormatFlagsException;
+import java.util.IllegalFormatPrecisionException;
+import java.util.IllegalFormatWidthException;
+import java.util.IllformedLocaleException;
+import java.util.InputMismatchException;
+import java.util.IntSummaryStatistics;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.LongSummaryStatistics;
+import java.util.Map;
+import java.util.MissingFormatArgumentException;
+import java.util.MissingFormatWidthException;
+import java.util.MissingResourceException;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+import java.util.PrimitiveIterator;
+import java.util.PriorityQueue;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import java.util.PropertyResourceBundle;
+import java.util.Queue;
+import java.util.Random;
+import java.util.RandomAccess;
+import java.util.ResourceBundle;
+import java.util.Scanner;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.SimpleTimeZone;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.SplittableRandom;
+import java.util.Stack;
+import java.util.StringJoiner;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TooManyListenersException;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.UnknownFormatConversionException;
+import java.util.UnknownFormatFlagsException;
+import java.util.Vector;
+import java.util.WeakHashMap;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.Exchanger;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TransferQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongArray;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicMarkableReference;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.util.concurrent.atomic.AtomicStampedReference;
+import java.util.concurrent.atomic.DoubleAccumulator;
+import java.util.concurrent.atomic.DoubleAdder;
+import java.util.concurrent.atomic.LongAccumulator;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.concurrent.locks.AbstractOwnableSynchronizer;
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.LockSupport;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.StampedLock;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.BinaryOperator;
+import java.util.function.BooleanSupplier;
+import java.util.function.Consumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.DoubleConsumer;
+import java.util.function.DoubleFunction;
+import java.util.function.DoublePredicate;
+import java.util.function.DoubleSupplier;
+import java.util.function.DoubleToIntFunction;
+import java.util.function.DoubleToLongFunction;
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.Function;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntSupplier;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.LongFunction;
+import java.util.function.LongPredicate;
+import java.util.function.LongSupplier;
+import java.util.function.LongToDoubleFunction;
+import java.util.function.LongToIntFunction;
+import java.util.function.LongUnaryOperator;
+import java.util.function.ObjDoubleConsumer;
+import java.util.function.ObjIntConsumer;
+import java.util.function.ObjLongConsumer;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleBiFunction;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntBiFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongBiFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.UnaryOperator;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.stream.BaseStream;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+public class Java8PublicClasses {
+
+    // java.io
+    private static final Class<?>[] JAVA_IO = { BufferedInputStream.class, 
BufferedOutputStream.class, BufferedReader.class, BufferedWriter.class,
+            ByteArrayInputStream.class, ByteArrayOutputStream.class, 
CharArrayReader.class, CharArrayWriter.class, Closeable.class, Console.class,
+            DataInput.class, DataInputStream.class, DataOutput.class, 
DataOutputStream.class, File.class, FileDescriptor.class, FileInputStream.class,
+            FileOutputStream.class, FilePermission.class, FileReader.class, 
FileWriter.class, FilterInputStream.class, FilterOutputStream.class,
+            FilterReader.class, FilterWriter.class, Flushable.class, 
InputStream.class, InputStreamReader.class, LineNumberReader.class, 
ObjectInput.class,
+            ObjectInputStream.class, ObjectOutput.class, 
ObjectOutputStream.class, ObjectStreamClass.class, ObjectStreamField.class, 
OutputStream.class,
+            OutputStreamWriter.class, PipedInputStream.class, 
PipedOutputStream.class, PipedReader.class, PipedWriter.class, 
PrintStream.class,
+            PrintWriter.class, PushbackInputStream.class, 
PushbackReader.class, RandomAccessFile.class, Reader.class, 
SequenceInputStream.class,
+            Serializable.class, SerializablePermission.class, 
StreamTokenizer.class, StringReader.class, StringWriter.class, Writer.class, 
Externalizable.class,
+            FileFilter.class, FilenameFilter.class, 
ObjectInputValidation.class,
+            // Exceptions
+            CharConversionException.class, EOFException.class, 
FileNotFoundException.class, InterruptedIOException.class, 
InvalidClassException.class,
+            InvalidObjectException.class, IOException.class, 
NotActiveException.class, NotSerializableException.class, 
ObjectStreamException.class,
+            OptionalDataException.class, StreamCorruptedException.class, 
SyncFailedException.class, UnsupportedEncodingException.class,
+            UTFDataFormatException.class, WriteAbortedException.class, 
UncheckedIOException.class };
+
+    // java.lang
+    private static final Class<?>[] JAVA_LANG = { Appendable.class, 
AutoCloseable.class, Boolean.class, Byte.class, CharSequence.class, 
Character.class,
+            Class.class, ClassLoader.class, ClassValue.class, Cloneable.class, 
Comparable.class, /* Compiler.class, */ Double.class, Enum.class, Float.class,
+            InheritableThreadLocal.class, Integer.class, Iterable.class, 
Long.class, Math.class, Number.class, Object.class, Package.class, 
Process.class,
+            ProcessBuilder.class, Readable.class, Runnable.class, 
Runtime.class, RuntimePermission.class, SecurityManager.class, Short.class,
+            StackTraceElement.class, StrictMath.class, String.class, 
StringBuffer.class, StringBuilder.class, System.class, Thread.class, 
ThreadGroup.class,
+            ThreadLocal.class, Throwable.class, Void.class,
+            // Exceptions
+            ArithmeticException.class, ArrayIndexOutOfBoundsException.class, 
ArrayStoreException.class, ClassCastException.class, 
ClassNotFoundException.class,
+            CloneNotSupportedException.class, 
EnumConstantNotPresentException.class, Exception.class, 
IllegalAccessException.class,
+            IllegalArgumentException.class, 
IllegalMonitorStateException.class, IllegalStateException.class, 
IllegalThreadStateException.class,
+            IndexOutOfBoundsException.class, InstantiationException.class, 
InterruptedException.class, NegativeArraySizeException.class,
+            NoSuchFieldException.class, NoSuchMethodException.class, 
NullPointerException.class, NumberFormatException.class,
+            ReflectiveOperationException.class, RuntimeException.class, 
SecurityException.class, StringIndexOutOfBoundsException.class,
+            TypeNotPresentException.class, UnsupportedOperationException.class,
+            // Errors
+            AbstractMethodError.class, AssertionError.class, 
BootstrapMethodError.class, ClassCircularityError.class, 
ClassFormatError.class, Error.class,
+            ExceptionInInitializerError.class, IllegalAccessError.class, 
IncompatibleClassChangeError.class, InstantiationError.class, 
InternalError.class,
+            LinkageError.class, NoClassDefFoundError.class, 
NoSuchFieldError.class, NoSuchMethodError.class, OutOfMemoryError.class, 
StackOverflowError.class,
+            ThreadDeath.class, UnknownError.class, UnsatisfiedLinkError.class, 
UnsupportedClassVersionError.class, VerifyError.class,
+            VirtualMachineError.class };
+
+    // java.lang.annotation
+    private static final Class<?>[] JAVA_LANG_ANNOTATION = { Annotation.class, 
Documented.class, Inherited.class, Retention.class, Target.class,
+            AnnotationFormatError.class, 
AnnotationTypeMismatchException.class, IncompleteAnnotationException.class, 
Repeatable.class, Native.class };
+
+    // java.lang.invoke
+    private static final Class<?>[] JAVA_LANG_INVOKE = { CallSite.class, 
ConstantCallSite.class, MethodHandle.class, MethodHandleInfo.class,
+            MethodHandles.class, MethodType.class, MutableCallSite.class, 
SwitchPoint.class, VolatileCallSite.class, WrongMethodTypeException.class,
+            LambdaMetafactory.class };
+
+    // java.lang.ref
+    private static final Class<?>[] JAVA_LANG_REF = { PhantomReference.class, 
Reference.class, ReferenceQueue.class, SoftReference.class,
+            WeakReference.class };
+
+    // java.lang.reflect
+    private static final Class<?>[] JAVA_LANG_REFLECT = { 
AccessibleObject.class, AnnotatedElement.class, Array.class, Constructor.class,
+            Executable.class, Field.class, GenericArrayType.class, 
GenericDeclaration.class, InvocationHandler.class, Member.class, Method.class,
+            Modifier.class, Parameter.class, ParameterizedType.class, 
Proxy.class, ReflectPermission.class, Type.class, TypeVariable.class, 
WildcardType.class,
+            AnnotatedType.class, AnnotatedArrayType.class, 
AnnotatedParameterizedType.class, AnnotatedTypeVariable.class, 
AnnotatedWildcardType.class,
+            InvocationTargetException.class, 
MalformedParameterizedTypeException.class, UndeclaredThrowableException.class };
+
+    // java.math
+    private static final Class<?>[] JAVA_MATH = { BigDecimal.class, 
BigInteger.class, MathContext.class, RoundingMode.class };
+
+    // java.net
+    private static final Class<?>[] JAVA_NET = { Authenticator.class, 
CacheRequest.class, CacheResponse.class, ContentHandler.class,
+            CookieHandler.class, CookieManager.class, CookiePolicy.class, 
CookieStore.class, DatagramPacket.class, DatagramSocket.class,
+            DatagramSocketImpl.class, FileNameMap.class, HttpCookie.class, 
HttpURLConnection.class, IDN.class, Inet4Address.class, Inet6Address.class,
+            InetAddress.class, InetSocketAddress.class, 
InterfaceAddress.class, JarURLConnection.class, MulticastSocket.class, 
NetPermission.class,
+            NetworkInterface.class, PasswordAuthentication.class, Proxy.class, 
ProxySelector.class, ResponseCache.class, SecureCacheResponse.class,
+            ServerSocket.class, Socket.class, SocketAddress.class, 
SocketImpl.class, SocketOption.class, SocketOptions.class, 
SocketPermission.class,
+            StandardProtocolFamily.class, StandardSocketOptions.class, 
URI.class, URL.class, URLClassLoader.class, URLConnection.class, 
URLDecoder.class,
+            URLEncoder.class, URLStreamHandler.class, BindException.class, 
ConnectException.class, HttpRetryException.class, MalformedURLException.class,
+            NoRouteToHostException.class, PortUnreachableException.class, 
ProtocolException.class, SocketException.class, SocketTimeoutException.class,
+            UnknownHostException.class, UnknownServiceException.class, 
URISyntaxException.class };
+
+    // java.nio
+    private static final Class<?>[] JAVA_NIO = { Buffer.class, 
ByteBuffer.class, ByteOrder.class, CharBuffer.class, DoubleBuffer.class,
+            FloatBuffer.class, IntBuffer.class, LongBuffer.class, 
MappedByteBuffer.class, ShortBuffer.class, BufferOverflowException.class,
+            BufferUnderflowException.class, InvalidMarkException.class, 
ReadOnlyBufferException.class };
+
+    // java.nio.charset
+    private static final Class<?>[] JAVA_NIO_CHARSET = { Charset.class, 
CharsetDecoder.class, CharsetEncoder.class, CoderResult.class,
+            CodingErrorAction.class, StandardCharsets.class, 
CharacterCodingException.class, IllegalCharsetNameException.class, 
MalformedInputException.class,
+            UnmappableCharacterException.class, 
UnsupportedCharsetException.class };
+
+    // java.nio.file
+    private static final Class<?>[] JAVA_NIO_FILE = { DirectoryStream.class, 
FileSystem.class, FileSystems.class, FileVisitOption.class,
+            FileVisitResult.class, FileVisitor.class, Files.class, 
LinkOption.class, OpenOption.class, Path.class, PathMatcher.class, Paths.class,
+            SimpleFileVisitor.class, StandardCopyOption.class, 
StandardOpenOption.class, StandardWatchEventKinds.class, WatchEvent.class, 
WatchKey.class,
+            WatchService.class, Watchable.class, AccessDeniedException.class, 
AtomicMoveNotSupportedException.class, ClosedDirectoryStreamException.class,
+            ClosedFileSystemException.class, 
ClosedWatchServiceException.class, DirectoryIteratorException.class, 
DirectoryNotEmptyException.class,
+            FileAlreadyExistsException.class, FileSystemException.class, 
FileSystemLoopException.class, FileSystemNotFoundException.class,
+            InvalidPathException.class, NoSuchFileException.class, 
NotDirectoryException.class, NotLinkException.class, 
ProviderMismatchException.class,
+            ProviderNotFoundException.class, ReadOnlyFileSystemException.class 
};
+
+    // java.nio.file.attribute
+    private static final Class<?>[] JAVA_NIO_FILE_ATTRIBUTE = { 
AclEntry.class, AclEntryFlag.class, AclEntryPermission.class, 
AclEntryType.class,
+            AclFileAttributeView.class, AttributeView.class, 
BasicFileAttributeView.class, BasicFileAttributes.class, 
DosFileAttributeView.class,
+            DosFileAttributes.class, FileAttribute.class, 
FileAttributeView.class, FileOwnerAttributeView.class, 
FileStoreAttributeView.class, FileTime.class,
+            GroupPrincipal.class, PosixFileAttributeView.class, 
PosixFileAttributes.class, PosixFilePermission.class, 
PosixFilePermissions.class,
+            UserDefinedFileAttributeView.class, UserPrincipal.class, 
UserPrincipalLookupService.class, UserPrincipalNotFoundException.class };
+
+    // java.security
+    private static final Class<?>[] JAVA_SECURITY = { 
AccessControlContext.class, AccessController.class, 
AlgorithmParameterGenerator.class,
+            AlgorithmParameters.class, AlgorithmParametersSpi.class, 
AllPermission.class, AuthProvider.class, BasicPermission.class, 
Certificate.class,
+            CodeSigner.class, CodeSource.class, DigestInputStream.class, 
DigestOutputStream.class, DomainCombiner.class, Guard.class, 
GuardedObject.class,
+            Identity.class, IdentityScope.class, Key.class, KeyFactory.class, 
KeyFactorySpi.class, KeyPair.class, KeyPairGenerator.class,
+            KeyPairGeneratorSpi.class, KeyRep.class, KeyStore.class, 
KeyStoreSpi.class, MessageDigest.class, MessageDigestSpi.class, 
Permission.class,
+            PermissionCollection.class, Permissions.class, Policy.class, 
PolicySpi.class, Principal.class, PrivateKey.class, PrivilegedAction.class,
+            PrivilegedActionException.class, PrivilegedExceptionAction.class, 
ProtectionDomain.class, Provider.class, PublicKey.class, 
SecureClassLoader.class,
+            SecureRandom.class, SecureRandomSpi.class, Security.class, 
SecurityPermission.class, Signature.class, SignatureException.class, 
SignatureSpi.class,
+            SignedObject.class, Signer.class, java.security.Timestamp.class, 
UnrecoverableEntryException.class, UnrecoverableKeyException.class,
+            UnresolvedPermission.class, AccessControlException.class, 
DigestException.class, GeneralSecurityException.class,
+            InvalidAlgorithmParameterException.class, 
InvalidKeyException.class, InvalidParameterException.class, KeyException.class,
+            KeyManagementException.class, KeyStoreException.class, 
NoSuchAlgorithmException.class, NoSuchProviderException.class, 
ProviderException.class };
+
+    // java.sql
+    private static final Class<?>[] JAVA_SQL = { Array.class, Blob.class, 
CallableStatement.class, Clob.class, Connection.class, DatabaseMetaData.class,
+            java.sql.Date.class, Driver.class, DriverManager.class, 
DriverPropertyInfo.class, NClob.class, ParameterMetaData.class, 
PreparedStatement.class,
+            Ref.class, ResultSet.class, ResultSetMetaData.class, RowId.class, 
Savepoint.class, SQLData.class, SQLInput.class, SQLOutput.class,
+            SQLPermission.class, SQLXML.class, Statement.class, Struct.class, 
Time.class, Timestamp.class, Types.class, Wrapper.class,
+            BatchUpdateException.class, DataTruncation.class, 
SQLClientInfoException.class, SQLException.class, SQLDataException.class,
+            SQLFeatureNotSupportedException.class, 
SQLIntegrityConstraintViolationException.class, 
SQLInvalidAuthorizationSpecException.class,
+            SQLNonTransientConnectionException.class, 
SQLNonTransientException.class, SQLRecoverableException.class, 
SQLSyntaxErrorException.class,
+            SQLTimeoutException.class, SQLTransactionRollbackException.class, 
SQLTransientConnectionException.class, SQLTransientException.class,
+            SQLWarning.class };
+
+    // java.text
+    private static final Class<?>[] JAVA_TEXT = { Annotation.class, 
AttributedCharacterIterator.class, AttributedString.class, Bidi.class,
+            BreakIterator.class, CharacterIterator.class, ChoiceFormat.class, 
CollationElementIterator.class, CollationKey.class, Collator.class,
+            DateFormat.class, DateFormatSymbols.class, DecimalFormat.class, 
DecimalFormatSymbols.class, FieldPosition.class, Format.class, 
MessageFormat.class,
+            Normalizer.class, NumberFormat.class, ParsePosition.class, 
RuleBasedCollator.class, SimpleDateFormat.class, StringCharacterIterator.class,
+            ParseException.class };
+
+    // java.time
+    private static final Class<?>[] JAVA_TIME = { Clock.class, 
DateTimeException.class, DayOfWeek.class, Duration.class, Instant.class, 
LocalDate.class,
+            LocalDateTime.class, LocalTime.class, Month.class, MonthDay.class, 
OffsetDateTime.class, OffsetTime.class, Period.class, Year.class,
+            YearMonth.class, ZonedDateTime.class, ZoneId.class, 
ZoneOffset.class };
+
+    // java.time.chrono
+    private static final Class<?>[] JAVA_TIME_CHRONO = { 
AbstractChronology.class, ChronoLocalDate.class, ChronoLocalDateTime.class, 
Chronology.class,
+            ChronoPeriod.class, ChronoZonedDateTime.class, Era.class, 
HijrahChronology.class, HijrahDate.class, HijrahEra.class, IsoChronology.class,
+            IsoEra.class, JapaneseChronology.class, JapaneseDate.class, 
JapaneseEra.class, MinguoChronology.class, MinguoDate.class, MinguoEra.class,
+            ThaiBuddhistChronology.class, ThaiBuddhistDate.class, 
ThaiBuddhistEra.class };
+
+    // java.time.format
+    private static final Class<?>[] JAVA_TIME_FORMAT = { 
DateTimeFormatter.class, DateTimeFormatterBuilder.class, 
DateTimeParseException.class,
+            DecimalStyle.class, FormatStyle.class, ResolverStyle.class, 
SignStyle.class, TextStyle.class };
+
+    // java.time.temporal
+    private static final Class<?>[] JAVA_TIME_TEMPORAL = { ChronoField.class, 
ChronoUnit.class, IsoFields.class, JulianFields.class, Temporal.class,
+            TemporalAccessor.class, TemporalAdjuster.class, 
TemporalAdjusters.class, TemporalAmount.class, TemporalField.class, 
TemporalQueries.class,
+            TemporalQuery.class, TemporalUnit.class, ValueRange.class, 
WeekFields.class, UnsupportedTemporalTypeException.class };
+
+    // java.time.zone
+    private static final Class<?>[] JAVA_TIME_ZONE = { 
ZoneOffsetTransition.class, ZoneOffsetTransitionRule.class, ZoneRules.class,
+            ZoneRulesException.class, ZoneRulesProvider.class };
+
+    // java.util
+    private static final Class<?>[] JAVA_UTIL = { AbstractCollection.class, 
AbstractList.class, AbstractMap.class, AbstractQueue.class,
+            AbstractSequentialList.class, AbstractSet.class, ArrayDeque.class, 
ArrayList.class, Arrays.class, Base64.class, BitSet.class, Calendar.class,
+            Collection.class, Collections.class, Comparator.class, 
Currency.class, Date.class, Deque.class, Dictionary.class, 
DoubleSummaryStatistics.class,
+            EnumMap.class, EnumSet.class, Enumeration.class, 
EventListener.class, EventListenerProxy.class, EventObject.class, 
FormattableFlags.class,
+            Formatter.class, GregorianCalendar.class, HashMap.class, 
HashSet.class, Hashtable.class, IdentityHashMap.class, 
IntSummaryStatistics.class,
+            Iterator.class, LinkedHashMap.class, LinkedHashSet.class, 
LinkedList.class, List.class, ListIterator.class, ListResourceBundle.class, 
Locale.class,
+            LongSummaryStatistics.class, Map.class, NavigableMap.class, 
NavigableSet.class, Objects.class, Observable.class, Observer.class, 
Optional.class,
+            OptionalDouble.class, OptionalInt.class, OptionalLong.class, 
PrimitiveIterator.class, PriorityQueue.class, Properties.class,
+            PropertyPermission.class, PropertyResourceBundle.class, 
Queue.class, Random.class, RandomAccess.class, ResourceBundle.class, 
Scanner.class,
+            ServiceLoader.class, Set.class, SimpleTimeZone.class, 
SortedMap.class, SortedSet.class, Spliterator.class, Spliterators.class,
+            SplittableRandom.class, Stack.class, StringJoiner.class, 
StringTokenizer.class, Timer.class, TimerTask.class, TimeZone.class, 
TreeMap.class,
+            TreeSet.class, UUID.class, Vector.class, WeakHashMap.class, 
Formattable.class,
+            // Exceptions
+            ConcurrentModificationException.class, 
DuplicateFormatFlagsException.class, EmptyStackException.class, 
FormatFlagsConversionMismatchException.class,
+            FormatterClosedException.class, 
IllegalFormatCodePointException.class, IllegalFormatConversionException.class, 
IllegalFormatException.class,
+            IllegalFormatFlagsException.class, 
IllegalFormatPrecisionException.class, IllegalFormatWidthException.class, 
IllformedLocaleException.class,
+            InputMismatchException.class, 
InvalidPropertiesFormatException.class, MissingFormatArgumentException.class, 
MissingFormatWidthException.class,
+            MissingResourceException.class, NoSuchElementException.class, 
TooManyListenersException.class, UnknownFormatConversionException.class,
+            UnknownFormatFlagsException.class, ServiceConfigurationError.class 
};
+
+    // java.util.concurrent
+    private static final Class<?>[] JAVA_UTIL_CONCURRENT = { 
AbstractExecutorService.class, ArrayBlockingQueue.class, BlockingDeque.class,
+            BlockingQueue.class, Callable.class, CompletableFuture.class, 
CompletionException.class, CompletionService.class, ConcurrentHashMap.class,
+            ConcurrentLinkedDeque.class, ConcurrentLinkedQueue.class, 
ConcurrentMap.class, ConcurrentNavigableMap.class, ConcurrentSkipListMap.class,
+            ConcurrentSkipListSet.class, CopyOnWriteArrayList.class, 
CopyOnWriteArraySet.class, CountDownLatch.class, CountedCompleter.class,
+            CyclicBarrier.class, Delayed.class, DelayQueue.class, 
Exchanger.class, Executor.class, ExecutorCompletionService.class, 
ExecutorService.class,
+            Executors.class, ForkJoinPool.class, ForkJoinTask.class, 
ForkJoinWorkerThread.class, Future.class, FutureTask.class, 
LinkedBlockingDeque.class,
+            LinkedBlockingQueue.class, LinkedTransferQueue.class, 
Phaser.class, PriorityBlockingQueue.class, RecursiveAction.class, 
RecursiveTask.class,
+            RejectedExecutionHandler.class, RunnableFuture.class, 
RunnableScheduledFuture.class, ScheduledExecutorService.class, 
ScheduledFuture.class,
+            ScheduledThreadPoolExecutor.class, Semaphore.class, 
SynchronousQueue.class, ThreadFactory.class, ThreadLocalRandom.class, 
ThreadPoolExecutor.class,
+            TimeUnit.class, TransferQueue.class, BrokenBarrierException.class, 
CancellationException.class, CompletionException.class, 
ExecutionException.class,
+            RejectedExecutionException.class, TimeoutException.class };
+
+    // java.util.concurrent.atomic
+    private static final Class<?>[] JAVA_UTIL_CONCURRENT_ATOMIC = { 
AtomicBoolean.class, AtomicInteger.class, AtomicIntegerArray.class,
+            AtomicIntegerFieldUpdater.class, AtomicLong.class, 
AtomicLongArray.class, AtomicLongFieldUpdater.class, 
AtomicMarkableReference.class,
+            AtomicReference.class, AtomicReferenceArray.class, 
AtomicReferenceFieldUpdater.class, AtomicStampedReference.class, 
DoubleAccumulator.class,
+            DoubleAdder.class, LongAccumulator.class, LongAdder.class };
+
+    // java.util.concurrent.locks
+    private static final Class<?>[] JAVA_UTIL_CONCURRENT_LOCKS = { 
AbstractOwnableSynchronizer.class, AbstractQueuedLongSynchronizer.class,
+            AbstractQueuedSynchronizer.class, Condition.class, Lock.class, 
LockSupport.class, ReadWriteLock.class, ReentrantLock.class,
+            ReentrantReadWriteLock.class, StampedLock.class };
+
+    // java.util.function
+    private static final Class<?>[] JAVA_UTIL_FUNCTION = { BiConsumer.class, 
BiFunction.class, BinaryOperator.class, BiPredicate.class,
+            BooleanSupplier.class, Consumer.class, DoubleBinaryOperator.class, 
DoubleConsumer.class, DoubleFunction.class, DoublePredicate.class,
+            DoubleSupplier.class, DoubleToIntFunction.class, 
DoubleToLongFunction.class, DoubleUnaryOperator.class, Function.class, 
IntBinaryOperator.class,
+            IntConsumer.class, IntFunction.class, IntPredicate.class, 
IntSupplier.class, IntToDoubleFunction.class, IntToLongFunction.class,
+            IntUnaryOperator.class, LongBinaryOperator.class, 
LongConsumer.class, LongFunction.class, LongPredicate.class, LongSupplier.class,
+            LongToDoubleFunction.class, LongToIntFunction.class, 
LongUnaryOperator.class, ObjDoubleConsumer.class, ObjIntConsumer.class, 
ObjLongConsumer.class,
+            Predicate.class, Supplier.class, ToDoubleBiFunction.class, 
ToDoubleFunction.class, ToIntBiFunction.class, ToIntFunction.class,
+            ToLongBiFunction.class, ToLongFunction.class, UnaryOperator.class 
};
+
+    // java.util.regex
+    private static final Class<?>[] JAVA_UTIL_REGEX = { MatchResult.class, 
Matcher.class, Pattern.class, PatternSyntaxException.class };
+
+    // java.util.stream
+    private static final Class<?>[] JAVA_UTIL_STREAM = { BaseStream.class, 
Collector.class, Collectors.class, DoubleStream.class, IntStream.class,
+            LongStream.class, Stream.class, StreamSupport.class };
+
+    private static final Class<?>[] ALL = addAll(JAVA_LANG, 
JAVA_LANG_ANNOTATION, JAVA_LANG_INVOKE,
+            JAVA_LANG_REF, JAVA_LANG_REFLECT, JAVA_MATH, JAVA_IO, JAVA_NIO, 
JAVA_NIO_CHARSET,
+            JAVA_NIO_FILE, JAVA_NIO_FILE_ATTRIBUTE, JAVA_UTIL, 
JAVA_UTIL_CONCURRENT, JAVA_UTIL_CONCURRENT_ATOMIC,
+            JAVA_UTIL_CONCURRENT_LOCKS, JAVA_UTIL_FUNCTION, JAVA_UTIL_STREAM, 
JAVA_UTIL_REGEX, JAVA_TIME,
+            JAVA_TIME_CHRONO, JAVA_TIME_FORMAT, JAVA_TIME_TEMPORAL, 
JAVA_TIME_ZONE, JAVA_NET, JAVA_TEXT,
+            JAVA_SQL, JAVA_SECURITY);
+
+    @SafeVarargs
+    private static Class<?>[] addAll(final Class<?>[]... arrays) {
+        int newLen = 0;
+        for (final Class<?>[] array : arrays) {
+            newLen += array.length;
+        }
+        final Class<?>[] result = new Class<?>[newLen];
+        int i = 0;
+        for (final Class<?>[] array : arrays) {
+            System.arraycopy(array, 0, result, i, array.length);
+            i += array.length;
+        }
+        return result;
+    }
+
+    public static Class<?>[] getAll() {
+        return ALL.clone();
+    }
+}
diff --git a/src/test/java/org/apache/bcel/classfile/JavaClassCyclicTest.java 
b/src/test/java/org/apache/bcel/classfile/JavaClassCyclicTest.java
new file mode 100644
index 00000000..0140d2e8
--- /dev/null
+++ b/src/test/java/org/apache/bcel/classfile/JavaClassCyclicTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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
+ *
+ *   https://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.bcel.classfile;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.ByteArrayInputStream;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.bcel.Repository;
+import org.apache.bcel.util.SyntheticRepository;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for cyclic hierarchy vulnerabilities in {@link JavaClass}. These 
tests demonstrate CWE-674 (Uncontrolled Recursion) vulnerabilities: -
+ * getAllInterfaces(): infinite queue growth with cyclic interfaces - 
getSuperClasses(): infinite loop with cyclic superclasses Without the fix, 
these tests
+ * will fail. With the fix, they pass.
+ */
+class JavaClassCyclicTest {
+
+    private JavaClass cyclicClassA;
+
+    private JavaClass cyclicClassB;
+
+    private JavaClass cyclicInterfaceA;
+
+    private JavaClass cyclicInterfaceB;
+
+    private JavaClass cyclicTestClass;
+
+    private SyntheticRepository repo;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        repo = SyntheticRepository.getInstance();
+        Repository.setRepository(repo);
+        // Create cyclic interfaces: A extends B, B extends A
+        final byte[] interfaceABytes = 
JavaClassTest.createInterface("CyclicInterfaceA", "CyclicInterfaceB");
+        final byte[] interfaceBBytes = 
JavaClassTest.createInterface("CyclicInterfaceB", "CyclicInterfaceA");
+        final byte[] testClassBytes = 
JavaClassTest.createClass("CyclicTestClass", "java.lang.Object", 
"CyclicInterfaceA");
+        cyclicInterfaceA = new ClassParser(new 
ByteArrayInputStream(interfaceABytes), "CyclicInterfaceA.class").parse();
+        cyclicInterfaceB = new ClassParser(new 
ByteArrayInputStream(interfaceBBytes), "CyclicInterfaceB.class").parse();
+        cyclicTestClass = new ClassParser(new 
ByteArrayInputStream(testClassBytes), "CyclicTestClass.class").parse();
+        repo.storeClass(cyclicInterfaceA);
+        repo.storeClass(cyclicInterfaceB);
+        repo.storeClass(cyclicTestClass);
+        // Create cyclic classes: A extends B, B extends A
+        final byte[] classABytes = JavaClassTest.createClass("CyclicClassA", 
"CyclicClassB");
+        final byte[] classBBytes = JavaClassTest.createClass("CyclicClassB", 
"CyclicClassA");
+        cyclicClassA = new ClassParser(new ByteArrayInputStream(classABytes), 
"CyclicClassA.class").parse();
+        cyclicClassB = new ClassParser(new ByteArrayInputStream(classBBytes), 
"CyclicClassB.class").parse();
+        repo.storeClass(cyclicClassA);
+        repo.storeClass(cyclicClassB);
+    }
+
+    @AfterEach
+    void tearDown() {
+        if (cyclicInterfaceA != null) {
+            repo.removeClass(cyclicInterfaceA);
+        }
+        if (cyclicInterfaceB != null) {
+            repo.removeClass(cyclicInterfaceB);
+        }
+        if (cyclicTestClass != null) {
+            repo.removeClass(cyclicTestClass);
+        }
+        if (cyclicClassA != null) {
+            repo.removeClass(cyclicClassA);
+        }
+        if (cyclicClassB != null) {
+            repo.removeClass(cyclicClassB);
+        }
+    }
+
+    /**
+     * Tests that getAllInterfaces() handles cyclic interface hierarchies 
gracefully. BUG: Without fix, getAllInterfaces() has no visited-node check 
before
+     * enqueueing, causing infinite queue growth and eventual heap exhaustion 
(OutOfMemoryError). FIXED: With the fix, already-visited nodes are skipped,
+     * preventing infinite growth.
+     */
+    @Test
+    void testGetAllInterfacesCyclic() throws Exception {
+        // TODO Use the test method once ClassCircularityError is implemented 
for this case
+        // test(cyclicTestClass::getAllInterfaces);
+        // TOOO Remove once the above is used
+        final ExecutorService executor = Executors.newSingleThreadExecutor();
+        try {
+            final Future<JavaClass[]> future = executor.submit(() -> 
cyclicTestClass.getAllInterfaces());
+            // Without fix: will timeout (infinite queue growth) or throw OOM
+            // With fix: completes quickly and returns the interfaces
+            final JavaClass[] interfaces = future.get(3, TimeUnit.SECONDS);
+            assertNotNull(interfaces, "getAllInterfaces() should return 
non-null array");
+            assertTrue(interfaces.length >= 2, "Should find at least 
CyclicInterfaceA and CyclicInterfaceB");
+        } catch (final TimeoutException e) {
+            fail("getAllInterfaces() timed out - infinite queue growth 
vulnerability detected");
+        } catch (final ExecutionException e) {
+            if (e.getCause() instanceof OutOfMemoryError) {
+                fail("getAllInterfaces() caused OutOfMemoryError - infinite 
queue growth vulnerability detected");
+            }
+            throw e;
+        } finally {
+            executor.shutdownNow();
+        }
+    }
+
+    /**
+     * Tests that getSuperClasses() detects cyclic superclass hierarchies. 
BUG: Without fix, getSuperClasses() has no cycle detection, causing an infinite 
loop
+     * when traversing cyclic superclass chains. FIXED: With the fix, 
ClassCircularityError is thrown when a cycle is detected.
+     */
+    @Test
+    void testGetSuperClassesCyclic() throws Exception {
+        test(cyclicClassA::getSuperClasses);
+    }
+
+    void test(final Callable<JavaClass[]> callable) throws Exception {
+        final ExecutorService executor = Executors.newSingleThreadExecutor();
+        try {
+            final Future<JavaClass[]> future = executor.submit(callable);
+            // Without fix: will timeout (infinite loop)
+            // With fix: throws ClassCircularityError immediately
+            future.get(3, TimeUnit.SECONDS);
+            fail("Should have thrown ClassCircularityError for cyclic 
hierarchy");
+        } catch (final TimeoutException e) {
+            fail("Timeout: infinite loop vulnerability detected");
+        } catch (final ExecutionException e) {
+            if (e.getCause() instanceof ClassCircularityError) {
+                // Expected with fix - test passes
+                return;
+            }
+            throw e;
+        } finally {
+            executor.shutdownNow();
+        }
+    }
+}
diff --git a/src/test/java/org/apache/bcel/classfile/JavaClassTest.java 
b/src/test/java/org/apache/bcel/classfile/JavaClassTest.java
index 0acfae84..1f92905b 100644
--- a/src/test/java/org/apache/bcel/classfile/JavaClassTest.java
+++ b/src/test/java/org/apache/bcel/classfile/JavaClassTest.java
@@ -27,172 +27,6 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.file.Path;
-import java.sql.Date;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.DayOfWeek;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.MonthDay;
-import java.time.OffsetDateTime;
-import java.time.OffsetTime;
-import java.time.Period;
-import java.time.Year;
-import java.time.YearMonth;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.util.AbstractCollection;
-import java.util.AbstractList;
-import java.util.AbstractMap;
-import java.util.AbstractQueue;
-import java.util.AbstractSequentialList;
-import java.util.AbstractSet;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.BitSet;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.ConcurrentModificationException;
-import java.util.Currency;
-import java.util.Deque;
-import java.util.Dictionary;
-import java.util.DoubleSummaryStatistics;
-import java.util.DuplicateFormatFlagsException;
-import java.util.EmptyStackException;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.EventListener;
-import java.util.EventListenerProxy;
-import java.util.EventObject;
-import java.util.FormatFlagsConversionMismatchException;
-import java.util.Formattable;
-import java.util.FormattableFlags;
-import java.util.Formatter;
-import java.util.FormatterClosedException;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
-import java.util.IllegalFormatCodePointException;
-import java.util.IllegalFormatConversionException;
-import java.util.IllegalFormatException;
-import java.util.IllegalFormatFlagsException;
-import java.util.IllegalFormatPrecisionException;
-import java.util.IllegalFormatWidthException;
-import java.util.IllformedLocaleException;
-import java.util.InputMismatchException;
-import java.util.IntSummaryStatistics;
-import java.util.InvalidPropertiesFormatException;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.ListResourceBundle;
-import java.util.Locale;
-import java.util.LongSummaryStatistics;
-import java.util.Map;
-import java.util.MissingFormatArgumentException;
-import java.util.MissingFormatWidthException;
-import java.util.MissingResourceException;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.Observable;
-import java.util.Observer;
-import java.util.Optional;
-import java.util.OptionalDouble;
-import java.util.OptionalInt;
-import java.util.OptionalLong;
-import java.util.PrimitiveIterator;
-import java.util.PriorityQueue;
-import java.util.Properties;
-import java.util.PropertyPermission;
-import java.util.PropertyResourceBundle;
-import java.util.Queue;
-import java.util.Random;
-import java.util.RandomAccess;
-import java.util.ResourceBundle;
-import java.util.Scanner;
-import java.util.ServiceConfigurationError;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.SimpleTimeZone;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.Spliterator;
-import java.util.Spliterators;
-import java.util.SplittableRandom;
-import java.util.Stack;
-import java.util.StringJoiner;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.TooManyListenersException;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
-import java.util.UnknownFormatConversionException;
-import java.util.UnknownFormatFlagsException;
-import java.util.Vector;
-import java.util.WeakHashMap;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.BiPredicate;
-import java.util.function.BinaryOperator;
-import java.util.function.BooleanSupplier;
-import java.util.function.Consumer;
-import java.util.function.DoubleBinaryOperator;
-import java.util.function.DoubleConsumer;
-import java.util.function.DoubleFunction;
-import java.util.function.DoublePredicate;
-import java.util.function.DoubleSupplier;
-import java.util.function.DoubleToIntFunction;
-import java.util.function.DoubleToLongFunction;
-import java.util.function.DoubleUnaryOperator;
-import java.util.function.Function;
-import java.util.function.IntBinaryOperator;
-import java.util.function.IntConsumer;
-import java.util.function.IntFunction;
-import java.util.function.IntPredicate;
-import java.util.function.IntSupplier;
-import java.util.function.IntToDoubleFunction;
-import java.util.function.IntToLongFunction;
-import java.util.function.IntUnaryOperator;
-import java.util.function.LongBinaryOperator;
-import java.util.function.LongConsumer;
-import java.util.function.LongFunction;
-import java.util.function.LongPredicate;
-import java.util.function.LongSupplier;
-import java.util.function.LongToDoubleFunction;
-import java.util.function.LongToIntFunction;
-import java.util.function.LongUnaryOperator;
-import java.util.function.ObjDoubleConsumer;
-import java.util.function.ObjIntConsumer;
-import java.util.function.ObjLongConsumer;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.function.ToDoubleBiFunction;
-import java.util.function.ToDoubleFunction;
-import java.util.function.ToIntBiFunction;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongBiFunction;
-import java.util.function.ToLongFunction;
-import java.util.function.UnaryOperator;
 
 import org.apache.bcel.Const;
 import org.apache.bcel.Repository;
@@ -216,68 +50,12 @@ class JavaClassTest {
 
     private static final String CLASS_NAME = "TargetClass";
 
-    private static final Class<?>[] CLASSES_JAVA_LANG = { 
AbstractMethodError.class, Appendable.class, ArithmeticException.class,
-            ArrayIndexOutOfBoundsException.class, ArrayStoreException.class, 
AssertionError.class, AutoCloseable.class, Boolean.class,
-            BootstrapMethodError.class, Byte.class, Character.class, 
Character.Subset.class, Character.UnicodeBlock.class, 
Character.UnicodeScript.class,
-            CharSequence.class, Class.class, ClassCastException.class, 
ClassCircularityError.class, ClassFormatError.class, ClassLoader.class,
-            ClassNotFoundException.class, ClassValue.class, Cloneable.class, 
CloneNotSupportedException.class, Comparable.class,
-            /* Compiler.class, */ Deprecated.class, Double.class, Enum.class, 
EnumConstantNotPresentException.class, Error.class, Exception.class,
-            ExceptionInInitializerError.class, Float.class, 
FunctionalInterface.class, IllegalAccessError.class, 
IllegalAccessException.class,
-            IllegalArgumentException.class, 
IllegalMonitorStateException.class, IllegalStateException.class, 
IllegalThreadStateException.class,
-            IncompatibleClassChangeError.class, 
IndexOutOfBoundsException.class, InheritableThreadLocal.class, 
InstantiationError.class,
-            InstantiationException.class, Integer.class, InternalError.class, 
InterruptedException.class, Iterable.class, LinkageError.class, Long.class,
-            Math.class, NegativeArraySizeException.class, 
NoClassDefFoundError.class, NoSuchFieldError.class, NoSuchFieldException.class,
-            NoSuchMethodError.class, NoSuchMethodException.class, 
NullPointerException.class, Number.class, NumberFormatException.class, 
Object.class,
-            OutOfMemoryError.class, Override.class, Package.class, 
Process.class, ProcessBuilder.class, ProcessBuilder.Redirect.class,
-            ProcessBuilder.Redirect.Type.class, Readable.class, 
ReflectiveOperationException.class, Runnable.class, Runtime.class, 
RuntimeException.class,
-            RuntimePermission.class, SafeVarargs.class, 
SecurityException.class, SecurityManager.class, Short.class, 
StackOverflowError.class,
-            StackTraceElement.class, StrictMath.class, String.class, 
StringBuffer.class, StringBuilder.class, StringIndexOutOfBoundsException.class,
-            SuppressWarnings.class, System.class, Thread.class, 
Thread.State.class, Thread.UncaughtExceptionHandler.class, ThreadDeath.class, 
ThreadGroup.class,
-            ThreadLocal.class, Throwable.class, TypeNotPresentException.class, 
UnknownError.class, UnsatisfiedLinkError.class,
-            UnsupportedClassVersionError.class, 
UnsupportedOperationException.class, VerifyError.class, 
VirtualMachineError.class, Void.class };
 // Doesn't compile due to cyclic inheritance
-//    private interface InterfaceA extends InterfaceB {
-//    }
+//  private interface InterfaceA extends InterfaceB {
+//  }
 //
-//    private interface InterfaceB extends InterfaceA {
-//    }
-
-    private static final Class<?>[] CLASSES_JAVA_TIME = { Clock.class, 
DateTimeException.class, DayOfWeek.class, Duration.class, Instant.class, 
LocalDate.class,
-            LocalDateTime.class, LocalTime.class, Month.class, MonthDay.class, 
OffsetDateTime.class, OffsetTime.class, Period.class, Year.class,
-            YearMonth.class, ZonedDateTime.class, ZoneId.class, 
ZoneOffset.class };
-
-    private static final Class<?>[] CLASSES_JAVA_UTIL = { 
AbstractCollection.class, AbstractList.class, AbstractMap.class, 
AbstractMap.SimpleEntry.class,
-            AbstractMap.SimpleImmutableEntry.class, AbstractQueue.class, 
AbstractSequentialList.class, AbstractSet.class, ArrayDeque.class, 
ArrayList.class,
-            Arrays.class, Base64.class, Base64.Decoder.class, 
Base64.Encoder.class, BitSet.class, Calendar.class, Calendar.Builder.class, 
Collection.class,
-            Collections.class, Comparator.class, 
ConcurrentModificationException.class, Currency.class, Date.class, Deque.class, 
Dictionary.class,
-            DoubleSummaryStatistics.class, 
DuplicateFormatFlagsException.class, EmptyStackException.class, EnumMap.class, 
Enumeration.class, EnumSet.class,
-            EventListener.class, EventListenerProxy.class, EventObject.class, 
Formattable.class, FormattableFlags.class,
-            FormatFlagsConversionMismatchException.class, Formatter.class, 
Formatter.BigDecimalLayoutForm.class, FormatterClosedException.class,
-            GregorianCalendar.class, HashMap.class, HashSet.class, 
Hashtable.class, IdentityHashMap.class, IllegalFormatCodePointException.class,
-            IllegalFormatConversionException.class, 
IllegalFormatException.class, IllegalFormatFlagsException.class, 
IllegalFormatPrecisionException.class,
-            IllegalFormatWidthException.class, IllformedLocaleException.class, 
InputMismatchException.class, IntSummaryStatistics.class,
-            InvalidPropertiesFormatException.class, Iterator.class, 
LinkedHashMap.class, LinkedHashSet.class, LinkedList.class, List.class, 
ListIterator.class,
-            ListResourceBundle.class, Locale.class, Locale.Builder.class, 
Locale.Category.class, Locale.FilteringMode.class, Locale.LanguageRange.class,
-            LongSummaryStatistics.class, Map.class, Map.Entry.class, 
MissingFormatArgumentException.class, MissingFormatWidthException.class,
-            MissingResourceException.class, NavigableMap.class, 
NavigableSet.class, NoSuchElementException.class, Objects.class, 
Observable.class,
-            Observer.class, Optional.class, OptionalDouble.class, 
OptionalInt.class, OptionalLong.class, PrimitiveIterator.class,
-            PrimitiveIterator.OfDouble.class, PrimitiveIterator.OfInt.class, 
PrimitiveIterator.OfLong.class, PriorityQueue.class, Properties.class,
-            PropertyPermission.class, PropertyResourceBundle.class, 
Queue.class, Random.class, RandomAccess.class, ResourceBundle.class,
-            ResourceBundle.Control.class, Scanner.class, 
ServiceConfigurationError.class, ServiceLoader.class, Set.class, 
SimpleTimeZone.class, SortedMap.class,
-            SortedSet.class, Spliterator.class, Spliterator.OfDouble.class, 
Spliterator.OfInt.class, Spliterator.OfLong.class, 
Spliterator.OfPrimitive.class,
-            Spliterators.class, Spliterators.AbstractDoubleSpliterator.class, 
Spliterators.AbstractIntSpliterator.class,
-            Spliterators.AbstractLongSpliterator.class, 
Spliterators.AbstractSpliterator.class, SplittableRandom.class, Stack.class, 
StringJoiner.class,
-            StringTokenizer.class, Timer.class, TimerTask.class, 
TimeZone.class, TooManyListenersException.class, TreeMap.class, TreeSet.class,
-            UnknownFormatConversionException.class, 
UnknownFormatFlagsException.class, UUID.class, Vector.class, WeakHashMap.class 
};
-
-    private static final Class<?>[] CLASSES_JAVA_UTIL_STREAM = { 
BiConsumer.class, BiFunction.class, BinaryOperator.class, BiPredicate.class,
-            BooleanSupplier.class, Consumer.class, DoubleBinaryOperator.class, 
DoubleConsumer.class, DoubleFunction.class, DoublePredicate.class,
-            DoubleSupplier.class, DoubleToIntFunction.class, 
DoubleToLongFunction.class, DoubleUnaryOperator.class, Function.class, 
IntBinaryOperator.class,
-            IntConsumer.class, IntFunction.class, IntPredicate.class, 
IntSupplier.class, IntToDoubleFunction.class, IntToLongFunction.class,
-            IntUnaryOperator.class, LongBinaryOperator.class, 
LongConsumer.class, LongFunction.class, LongPredicate.class, LongSupplier.class,
-            LongToDoubleFunction.class, LongToIntFunction.class, 
LongUnaryOperator.class, ObjDoubleConsumer.class, ObjIntConsumer.class, 
ObjLongConsumer.class,
-            Predicate.class, Supplier.class, ToDoubleBiFunction.class, 
ToDoubleFunction.class, ToIntBiFunction.class, ToIntFunction.class,
-            ToLongBiFunction.class, ToLongFunction.class, UnaryOperator.class 
};
+//  private interface InterfaceB extends InterfaceA {
+//  }
 
     @TempDir
     static Path tempDir;
@@ -285,68 +63,50 @@ class JavaClassTest {
     @BeforeAll
     static void beforeAll() throws Exception {
         // Create InterfaceA that extends InterfaceB (will create cycle)
-        createInterfaceA();
+        writeInterfaceA();
         // Create InterfaceB that extends InterfaceA (completes the cycle)
-        createInterfaceB();
+        writeInterfaceB();
         // Create a class that implements InterfaceA
-        createTargetClass();
+        writeTargetClass();
         // Cycle: InterfaceA -> InterfaceB -> InterfaceA -> ...
     }
 
-    private static byte[] createClass(final String name, final String 
extendsClass) throws IOException {
-        final ClassGen cg = new ClassGen(name, extendsClass, name + ".java", 
Const.ACC_PUBLIC, new String[] {});
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        cg.getJavaClass().dump(baos);
-        return baos.toByteArray();
+    static byte[] createClass(final String name, final String extendsClass) 
throws IOException {
+        return toByteArray(new ClassGen(name, extendsClass, name + ".java", 
Const.ACC_PUBLIC, new String[] {}));
     }
 
-    private static byte[] createClass(final String name, final String 
extendsClass, final String implementsInterface) throws IOException {
-        final ClassGen cg = new ClassGen(name, extendsClass, name + ".java", 
Const.ACC_PUBLIC, new String[] { implementsInterface });
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        cg.getJavaClass().dump(baos);
-        return baos.toByteArray();
+    static byte[] createClass(final String name, final String extendsClass, 
final String implementsInterface) throws IOException {
+        return toByteArray(new ClassGen(name, extendsClass, name + ".java", 
Const.ACC_PUBLIC, new String[] { implementsInterface }));
+    }
+
+    static byte[] createInterface(final String name, final String 
extendsInterface) throws IOException {
+        return toByteArray(new ClassGen(name, "java.lang.Object", name + 
".java", Const.ACC_PUBLIC | Const.ACC_INTERFACE | Const.ACC_ABSTRACT,
+                new String[] { extendsInterface }));
     }
 
-    private static byte[] createInterface(final String name, final String 
extendsInterface) throws IOException {
-        final ClassGen cg = new ClassGen(name, "java.lang.Object", name + 
".java", Const.ACC_PUBLIC | Const.ACC_INTERFACE | Const.ACC_ABSTRACT,
-                new String[] { extendsInterface });
+    static byte[] toByteArray(final ClassGen cg) throws IOException {
         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
         cg.getJavaClass().dump(baos);
         return baos.toByteArray();
     }
 
-    private static void createInterfaceA() throws Exception {
-        // Create InterfaceA that extends InterfaceB (creating part of the 
cycle)
-        final ClassGen cg = new ClassGen("InterfaceA", // class name
-                "java.lang.Object", // super class
-                "InterfaceA.java", // source file
-                Const.ACC_PUBLIC | Const.ACC_INTERFACE | Const.ACC_ABSTRACT, 
// access flags
-                new String[] { "InterfaceB" } // interfaces (extends 
InterfaceB)
-        );
-        // Create the class file
+    private static void writeInterfaceA() throws Exception {
+        // Create InterfaceA that extends InterfaceB
+        final ClassGen cg = new ClassGen("InterfaceA", "java.lang.Object", 
"InterfaceA.java", Const.ACC_PUBLIC | Const.ACC_INTERFACE | Const.ACC_ABSTRACT,
+                new String[] { "InterfaceB" });
         cg.getJavaClass().dump(tempDir.resolve("InterfaceA.class").toString());
     }
 
-    private static void createInterfaceB() throws Exception {
-        // Create InterfaceB that extends InterfaceA (completing the cycle)
-        final ClassGen cg = new ClassGen("InterfaceB", // class name
-                "java.lang.Object", // super class
-                "InterfaceB.java", // source file
-                Const.ACC_PUBLIC | Const.ACC_INTERFACE | Const.ACC_ABSTRACT, 
// access flags
-                new String[] { "InterfaceA" } // interfaces (extends 
InterfaceA)
-        );
-        // Create the class file
+    private static void writeInterfaceB() throws Exception {
+        // Create InterfaceB that extends InterfaceA
+        final ClassGen cg = new ClassGen("InterfaceB", "java.lang.Object", 
"InterfaceB.java", Const.ACC_PUBLIC | Const.ACC_INTERFACE | Const.ACC_ABSTRACT,
+                new String[] { "InterfaceA" });
         cg.getJavaClass().dump(tempDir.resolve("InterfaceB.class").toString());
     }
 
-    private static void createTargetClass() throws Exception {
+    private static void writeTargetClass() throws Exception {
         // Create a class that implements InterfaceA
-        final ClassGen cg = new ClassGen(CLASS_NAME, // class name
-                "java.lang.Object", // super class
-                "VulnerableClass.java", // source file
-                Const.ACC_PUBLIC, // access flags
-                new String[] { "InterfaceA" } // interfaces
-        );
+        final ClassGen cg = new ClassGen(CLASS_NAME, "java.lang.Object", 
"VulnerableClass.java", Const.ACC_PUBLIC, new String[] { "InterfaceA" });
         // Add default constructor
         final InstructionList il = new InstructionList();
         final MethodGen constructor = new MethodGen(Const.ACC_PUBLIC, 
Type.VOID, Type.NO_ARGS, new String[] {}, "<init>", CLASS_NAME, il, 
cg.getConstantPool());
@@ -362,22 +122,6 @@ class JavaClassTest {
         cg.getJavaClass().dump(tempDir.resolve(CLASS_NAME + 
".class").toString());
     }
 
-    static Class<?>[] getClassesJavaLang() {
-        return CLASSES_JAVA_LANG;
-    }
-
-    static Class<?>[] getClassesJavaTime() {
-        return CLASSES_JAVA_TIME;
-    }
-
-    static Class<?>[] getClassesJavaUtil() {
-        return CLASSES_JAVA_UTIL;
-    }
-
-    static Class<?>[] getClassesJavaUtilStream() {
-        return CLASSES_JAVA_UTIL_STREAM;
-    }
-
     private Field findFieldDoesNotExist(final Class<?> clazz) throws 
ClassNotFoundException {
         return 
Repository.lookupClass(clazz.getName()).findField("nonExistentField", Type.INT);
     }
@@ -435,29 +179,21 @@ class JavaClassTest {
     }
 
     @ParameterizedTest
-    @MethodSource("getClassesJavaLang")
-    @MethodSource("getClassesJavaTime")
-    @MethodSource("getClassesJavaUtil")
-    @MethodSource("getClassesJavaUtilStream")
+    @MethodSource("org.apache.bcel.Java8PublicClasses#getAll")
     void testFindFieldJavaLang(final Class<?> clazz) throws 
ClassNotFoundException {
         assertNull(findFieldDoesNotExist(clazz));
     }
 
     @ParameterizedTest
-    @MethodSource("getClassesJavaLang")
-    @MethodSource("getClassesJavaTime")
-    @MethodSource("getClassesJavaUtil")
-    @MethodSource("getClassesJavaUtilStream")
+    @MethodSource("org.apache.bcel.Java8PublicClasses#getAll")
     void testGetAllInterfaces(final Class<?> clazz) throws 
ClassNotFoundException {
         
assertNotNull(Repository.lookupClass(clazz.getName()).getAllInterfaces());
     }
 
     @ParameterizedTest
-    @MethodSource("getClassesJavaLang")
-    @MethodSource("getClassesJavaTime")
-    @MethodSource("getClassesJavaUtil")
-    @MethodSource("getClassesJavaUtilStream")
-    void testGetSuperClasses(final Class<?> clazz) throws 
ClassNotFoundException {
+    @MethodSource("org.apache.bcel.Java8PublicClasses#getAll")
+    void testGetSuperClassesAll(final Class<?> clazz) throws 
ClassNotFoundException {
         
assertNotNull(Repository.lookupClass(clazz.getName()).getSuperClasses());
     }
+
 }

Reply via email to