Class XReflection
Starting Points
Basic reflection starting points are through theClassHandle
methods:
of(Class): For static classes with known type at compile time.classHandle(): For general classes that have unknown type at compile time.ofMinecraft(): Specialized for Minecraft-related classes.namespaced(): String-based API for getting classes with Java code inside strings that is more readable.
Fallback
Some methods exist to choose between different values depending on the situation:v(int, Object): Basic Minecraft version-based value handler.any(ReflectiveHandle[])andanyOf(Callable[]): Advanced fallback-based support for all the reflection operations.
Others
Also, there are a few other non-reflection APIs in this class that are a bit "hacky" which is why they're here.getVersionInformation(): Useful string to include in your reflection related errors.throwCheckedException(Throwable): Force throw checked exceptions as unchecked.stacktrace(CompletableFuture): Add stacktrace information toCompletableFutures.relativizeSuppressedExceptions(Throwable): Relativize the stacktrace of exceptions that are thrown from the same location.
- Version:
- 11.2.1
- Author:
- Crypto Morin
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringMojang remapped their NMS in 1.17: Spigot Threadstatic final intstatic final intThe raw minor version number.static final StringMojang remapped their NMS in 1.17: Spigot Threadstatic final StringWe use reflection mainly to avoid writing a new class for version barrier.static final intThe raw patch version number.static final Set<MinecraftMapping> static final StringThe current version of XSeries. -
Method Summary
Modifier and TypeMethodDescriptionstatic <T,H extends ReflectiveHandle<T>>
AggregateReflectiveHandle<T, H> any(H... handles) static <T,H extends ReflectiveHandle<T>>
AggregateReflectiveHandle<T, H> static DynamicClassHandlestatic <T> T[]concatenate(T[] a, T[] b) static Stringstatic Class<?> getCraftClass(String name) Deprecated.static IntegergetLatestPatchNumberOf(int minorVersion) Gets the latest known patch number of the given minor version.static Class<?> getNMSClass(String name) Deprecated.useofMinecraft()static Class<?> getNMSClass(String packageName, String name) Deprecated.useofMinecraft()instead.static StringGets the full version information of the server.static ReflectiveNamespaceReadReflectiveNamespacefor more info.static StaticClassHandlestatic MinecraftClassHandlestatic <T extends Throwable>
TRelativize the stacktrace of exceptions that are thrown from the same location.static <T> CompletableFuture<T> stacktrace(CompletableFuture<T> completableFuture) Adds the stacktrace of the current thread in case an error occurs in the given Future.static booleansupports(int minorNumber) Checks whether the server version is equal or greater than the given version.static booleansupports(int minorNumber, int patchNumber) Checks whether the server version is equal or greater than the given version.static booleansupports(int majorNumber, int minorNumber, int patchNumber) A more friendly version ofsupports(int, int)for people with OCD.static booleansupportsPatch(int patchNumber) Deprecated.static RuntimeExceptionthrowCheckedException(Throwable exception) Throws a checked exception (seeException) silently without forcing the programmer to handle it.static Class<?> toArrayClass(Class<?> clazz) Gives an array version of a class.static <T> VersionHandle<T> static <T> VersionHandle<T> v(int version, int patch, T handle) static <T> VersionHandle<T> static <T> VersionHandle<T> v(int version, T handle) Gives thehandleobject if the server version is equal or greater than the given version.
-
Field Details
-
NMS_VERSION
We use reflection mainly to avoid writing a new class for version barrier. The version barrier is for NMS that uses the Minecraft version as the main package name.E.g. EntityPlayer in 1.15 is in the class
net.minecraft.server.v1_15_R1but in 1.14 it's innet.minecraft.server.v1_14_R1In order to maintain cross-version compatibility we cannot import these classes.Performance is not a concern for these specific statically initialized values.
This will no longer work because of Paper no-relocation strategy.
-
XSERIES_VERSION
The current version of XSeries. Mostly used for theXSkullAPI.- See Also:
-
MAJOR_NUMBER
public static final int MAJOR_NUMBER -
MINOR_NUMBER
public static final int MINOR_NUMBERThe raw minor version number. E.g.v1_17_R1to17- Since:
- 4.0.0
- See Also:
-
PATCH_NUMBER
public static final int PATCH_NUMBERThe raw patch version number. Refers to the major.minor.patch version scheme. E.g.v1.20.4to4v1.18.2to2v1.19.1to1
I'd not recommend developers to support individual patches at all. You should always support the latest patch. For example, between v1.14.0, v1.14.1, v1.14.2, v1.14.3 and v1.14.4 you should only support v1.14.4
This can be used to warn server owners when your plugin will break on older patches.
- Since:
- 7.0.0
- See Also:
-
CRAFTBUKKIT_PACKAGE
Mojang remapped their NMS in 1.17: Spigot Thread -
NMS_PACKAGE
Mojang remapped their NMS in 1.17: Spigot Thread -
SUPPORTED_MAPPINGS
-
-
Method Details
-
findNMSVersionString
-
getVersionInformation
Gets the full version information of the server. Useful for including in errors. "NMS" might return "Unknown NMS", which means that they're running a Paper server that removed the CraftBukkit NMS version guard.- Since:
- 7.0.0
-
getLatestPatchNumberOf
Gets the latest known patch number of the given minor version. For example: 1.14 -> 4, 1.17 -> 10 The latest version is expected to get newer patches, so make sure to account for unexpected results.- Parameters:
minorVersion- the minor version to get the patch number of.- Returns:
- the patch number of the given minor version if recognized, otherwise null.
- Since:
- 7.0.0
-
v
Gives thehandleobject if the server version is equal or greater than the given version. This method is purely for readability and should be always used withVersionHandle.orElse(Object).- Since:
- 5.0.0
- See Also:
-
v
- Since:
- 9.5.0
-
v
-
v
-
supports
public static boolean supports(int minorNumber) Checks whether the server version is equal or greater than the given version.- Parameters:
minorNumber- the version to compare the server version with.- Returns:
- true if the version is equal or newer, otherwise false.
- Since:
- 4.0.0
- See Also:
-
supports
public static boolean supports(int majorNumber, int minorNumber, int patchNumber) A more friendly version ofsupports(int, int)for people with OCD. -
supports
public static boolean supports(int minorNumber, int patchNumber) Checks whether the server version is equal or greater than the given version.- Parameters:
minorNumber- the minor version to compare the server version with.patchNumber- the patch number to compare the server version with.- Returns:
- true if the version is equal or newer, otherwise false.
- Since:
- 7.1.0
- See Also:
-
supportsPatch
Deprecated.Checks whether the server version is equal or greater than the given version.- Parameters:
patchNumber- the version to compare the server version with.- Returns:
- true if the version is equal or newer, otherwise false.
- Since:
- 7.0.0
- See Also:
-
getNMSClass
@Nonnull @Deprecated public static Class<?> getNMSClass(@Nullable String packageName, @Nonnull String name) Deprecated.useofMinecraft()instead.Get a NMS (net.minecraft.server) class which accepts a package for 1.17 compatibility.- Parameters:
packageName- the 1.17+ package name of this class.name- the name of the class.- Returns:
- the NMS class or null if not found.
- Throws:
RuntimeException- if the class could not be found.- Since:
- 4.0.0
- See Also:
-
getNMSClass
Deprecated.useofMinecraft()Get a NMSNMS_PACKAGEclass.- Parameters:
name- the name of the class.- Returns:
- the NMS class or null if not found.
- Throws:
RuntimeException- if the class could not be found.- Since:
- 1.0.0
- See Also:
-
getCraftClass
Deprecated.useofMinecraft()instead.Get a CraftBukkit (org.bukkit.craftbukkit) class.- Parameters:
name- the name of the class to load.- Returns:
- the CraftBukkit class or null if not found.
- Throws:
RuntimeException- if the class could not be found.- Since:
- 1.0.0
-
toArrayClass
Gives an array version of a class. For example if you wantedEntityPlayer[]you'd use:Class EntityPlayer = ReflectionUtils.getNMSClass("...", "EntityPlayer"); Class EntityPlayerArray = ReflectionUtils.toArrayClass(EntityPlayer);Note that this doesn't work on primitive classes.
- Parameters:
clazz- the class to get the array version of. You could use for multi-dimensions arrays too.- Throws:
RuntimeException- if the class could not be found.
-
ofMinecraft
- Since:
- v9.0.0
-
classHandle
- Since:
- v9.0.0
-
of
- Since:
- v11.0.0
-
namespaced
ReadReflectiveNamespacefor more info.- Since:
- v11.0.0
-
any
@SafeVarargs public static <T,H extends ReflectiveHandle<T>> AggregateReflectiveHandle<T,H> any(H... handles) - Since:
- v9.0.0
-
anyOf
@SafeVarargs public static <T,H extends ReflectiveHandle<T>> AggregateReflectiveHandle<T,H> anyOf(Callable<H>... handles) - Since:
- v9.0.0
-
relativizeSuppressedExceptions
Relativize the stacktrace of exceptions that are thrown from the same location. The suppressed exception's (Throwable.getSuppressed()) stacktrace are relativized against the given exceptions stacktrace.This is mostly useful when you have a trial-and-error mechanism that accumulates all the errors to throw them in case all the attempts have failed. This removes unnecessary line information to help the developer focus on important, non-repeated lines.
- Type Parameters:
T- the type of the exception.- Parameters:
ex- the exception to have it's suppressed exceptions relativized.- Returns:
- the same exception.
-
throwCheckedException
Throws a checked exception (seeException) silently without forcing the programmer to handle it. This is usually considered a very bad practice, as those errors are meant to be handled, so please use sparingly. You should just create aRuntimeExceptioninstead and putting the checked exception as a cause if necessary.Usage
void doStuff() throws IOException {} void rethrowAsRuntime() { try { doStuff(); } catch (IOException ex) { throw new RuntimeException(ex); } } void ignoreTheLawsOfJavaQuantumMechanics() { try { doStuff(); } catch (IOException ex) { throw XReflection.throwCheckedException(ex); } }- Returns:
null, but it's intended to be thrown, this is a hacky trick to stop the IDE from complaining about non-terminating statements.
-
stacktrace
@Experimental public static <T> CompletableFuture<T> stacktrace(@Nonnull CompletableFuture<T> completableFuture) Adds the stacktrace of the current thread in case an error occurs in the given Future. -
concatenate
@Internal public static <T> T[] concatenate(T[] a, T[] b)
-
ofMinecraft()instead.