Skip to content

Reflection ​

com.jsmacrosce.jsmacros.core.library.impl.FReflection

Since1.2.3

Loads classes and uses Java reflection through the script global Reflection.
Minecraft class and member names depend on the loader, runtime mappings, and Minecraft target;
they are not universally intermediary names. Primary class lookup uses this library's loader,
including jars added with loadJarFile(String). The two-name getClass(String, String) overload uses the default loader for its fallback. Legacy xyz.wagyourtail. names are rewritten before lookup.

Returned classes, methods and fields are ordinary Java reflection objects. Names absent from the shipped TypeScript package model are typed as unknown; raw Minecraft members are not modeled by those typings. Resolve methods separately from invoking them, for example with invokeMethod(Method, Object, Object...).

js
// Resolve and construct a JDK class, then look up and invoke a method separately.  
const ArrayList = Reflection.getClass("java.util.ArrayList");  
const list = Reflection.newInstance(ArrayList);  
list.add("diamond");  
const size = Reflection.getDeclaredMethod(ArrayList, "size");  
print(`the list holds ${Reflection.invokeMethod(size, list)}`);

A declared-field lookup can find non-public fields, but reading one requires access and may be denied by Java access restrictions.

Accessible in scripts via the global Reflection variable.

Nested types ​

Fields ​

classLoader ​

static classLoader: FReflection.CombinedVariableClassLoaderread-only#
Shared loader used by getClass(String) and loadJarFile(String).

Methods ​

compileJavaClass ​

compileJavaClass(String className, String code): Class<?>Since1.8.4#
Compiles source into a runtime class and keeps each compilation under the requested name. Each call creates a distinct class; previously returned classes and their instances are unaffected. Use the returned Class reference to construct instances or store them with FGlobalVars.putObject(String, Object). A JDK is required to compile classes.
// Recompiling the same name creates a separate class.
const first = Reflection.compileJavaClass("com.example.Counter",
  "package com.example; public class Counter { public int n = 0; }");
const second = Reflection.compileJavaClass("com.example.Counter",
  "package com.example; public class Counter { public int n = 100; }");
const versions = Reflection.getAllCompiledJavaClassVersions("com.example.Counter");
print(`that name now has ${versions.size()} compiled versions`);

// Keep the class reference to choose which version to instantiate.
const instance = Reflection.newInstance(first);
GlobalVars.putObject("counter", instance);
// getCompiledJavaClass gives the most recent compilation of that name
print(`and the newest is the second one: ${Reflection.getCompiledJavaClass("com.example.Counter") === second}`);

Parameters:

  • className: the fully qualified name of the class, including the package
  • code: the java code to compile
Returns: the newly compiled class

createClassBuilder ​

createClassBuilder(String cName, Class<T> clazz, Class<?>... interfaces): ClassBuilder<T>Since1.6.5#

Parameters:

  • cName: generated class name
  • clazz: superclass
  • interfaces: interfaces implemented by the generated class

Type Parameters:

  • T: superclass type
Returns: the class builder

createClassProxyBuilder ​

createClassProxyBuilder(Class<T> clazz, Class<?>... interfaces): ProxyBuilder<T>Since1.6.0#
Creates a builder for a guest-language proxy implementing the requested interfaces.

Parameters:

  • clazz: superclass to proxy
  • interfaces: interfaces implemented by the proxy

Type Parameters:

  • T: superclass type
Returns: the proxy builder

createLibrary ​

createLibrary(String className, String javaCode): voidSince1.8.4#
Compiles Java source as a class and registers it as a library. The class must carry a Library annotation and extend BaseLibrary (directly or through a supported per-exec or per-language base class).

Parameters:

  • className: the fully qualified name of the class, including the package
  • javaCode: the source code of the library

createLibraryBuilder ​

createLibraryBuilder(String name, boolean perExec, String... acceptedLangs): LibraryBuilder#
Creates a builder for a runtime-generated library class, configured with its script global, lifecycle, and supported languages. The generated class is registered for scripts only when LibraryBuilder.finishBuildAndFreeze() is called. LibraryBuilder.addConstructor() adds a public constructor whose parameters are determined by this builder's lifecycle and language configuration; if omitted, the builder supplies a forwarding constructor automatically.

Parameters:

  • name: name of the script global
  • perExec: whether to create a library per script run rather than per profile
  • acceptedLangs: guest languages allowed to use the library; empty means all
Returns: a builder for assembling the library class

getAllCompiledJavaClassVersions ​

getAllCompiledJavaClassVersions(String className): List<Class<?>>Since1.8.4#
Returns the compiled classes cached under the requested name, in compilation order.

Parameters:

  • className: the fully qualified class name
Returns: an immutable snapshot of compiled classes in compilation order, or an empty list if none are cached

getClass ​

getClass(String name): Class<T>Since1.2.3#
Resolves a fully qualified class name through this library's loader, including jars added by loadJarFile(String), and initializes the class. The nine lower-case Java primitive names, including void, resolve directly to their primitive classes. The legacy xyz.wagyourtail. package prefix is rewritten before loading. Returns an ordinary Class; use getClass(String, String) for an alternative name when the first is absent. Minecraft class names depend on the runtime mappings.

Parameters:

  • name: name of class like path.to.class

Type Parameters:

  • T: type represented by the resolved class
Returns: resolved class
getClass(String name, String name2): Class<T>Since1.2.3#
Tries the first class name, then the second only if the first lookup throws ClassNotFoundException. This can accommodate differing runtime mappings when the supplied names match them; it does not guarantee that either name exists on every version. The second lookup uses the default class loader, not this library's loader, so it does not use jars registered only through loadJarFile(String). A primitive first name resolves directly and does not fall back; a successfully resolved but unintended class also prevents fallback.
// Put the runtime's expected name first; the alternative is tried only if it is absent.
const List = Reflection.getClass("example.Missing", "java.util.ArrayList");
const list = Reflection.newInstance(List);
list.add("item");

Parameters:

  • name: first try
  • name2: second try

Type Parameters:

  • T: type represented by the resolved class
Returns: a Class reference.
getClass(): Class<?>#

Returns: Class<?>

getClassFromClassBuilderResult ​

getClassFromClassBuilderResult(String cName): Class<?>Since1.6.5#

Parameters:

  • cName: generated class name used to create the class
Returns: the generated class

getClassName ​

getClassName(Object o): StringSince1.3.1#
Returns the canonical name of a class or an object's runtime class. Canonical names use dots for nested classes; the result is null for local and anonymous classes. Arrays and primitive classes use their canonical names.
const ArrayList = Reflection.getClass("java.util.ArrayList");
// a Class names itself, whatever the instance it came from was
print(`the class is ${Reflection.getClassName(ArrayList)}`);
// an instance names its runtime type, which is the subclass
print(`the instance is ${Reflection.getClassName(Reflection.newInstance(ArrayList))}`);
// a primitive class names the primitive
print(`and a primitive is ${Reflection.getClassName(Reflection.getClass("int"))}`);

Parameters:

  • o: a Class or an object whose runtime class should be named
Returns: the canonical class name, or null if it has none

getCompiledJavaClass ​

getCompiledJavaClass(String className): Class<?>Since1.8.4#
Returns the most recently compiled class cached under the requested name.

Parameters:

  • className: the fully qualified class name
Returns: the most recently compiled class, or null if none is cached

getDeclaredField ​

getDeclaredField(Class<?> c, String name): FieldSince1.2.3#
Finds a field declared directly by the class, including non-public fields.

Parameters:

  • c: class to search
  • name: field name
Returns: the declared field

See:

getDeclaredField(Class<?> c, String name, String name2): FieldSince1.2.3#
Finds a declared field by trying name, then name2 if the first lookup throws NoSuchFieldException or SecurityException.

Parameters:

  • c: class declaring the field
  • name: primary field name
  • name2: fallback field name
Returns: the matching field

getDeclaredMethod ​

getDeclaredMethod(Class<?> c, String name, Class<?>... parameterTypes): MethodSince1.2.3#
Finds a method declared directly by the class, matching its exact parameter classes; it does not find inherited methods. Use getMethod(Class, String, Class...) for public methods including inherited ones. The two-name getDeclaredMethod(Class, String, String, Class...) overload retries with another method name. The returned Method must be invoked separately with invokeMethod(Method, Object, Object...). Non-public methods may require setAccessible(true), subject to Java access restrictions.
const StringClass = Reflection.getClass("java.lang.String");
const startsWith = Reflection.getDeclaredMethod(
  StringClass, "startsWith", StringClass);
print(Reflection.invokeMethod(startsWith, "hello", "he"));

Parameters:

  • c: the class to look the method up on
  • name: the method's name
  • parameterTypes: the exact classes of the method's parameters, none for no parameters
Returns: the method, which has to be invoked separately
getDeclaredMethod(Class<?> c, String name, String name2, Class<?>... parameterTypes): MethodSince1.2.3#
Finds a declared method by trying name, then name2 if lookup by the first name throws NoSuchMethodException or SecurityException. Both names use the same exact parameter types.

Parameters:

  • c: class declaring the method
  • name: primary method name
  • name2: fallback method name
  • parameterTypes: exact parameter types
Returns: the matching method

getField ​

getField(Class<?> c, String name): FieldSince1.6.0#
Finds a public field by name.

Parameters:

  • c: class to search
  • name: field name
Returns: the matching public field
getField(Class<?> c, String name, String name2): FieldSince1.6.0#
Returns a public field, trying name2 if lookup by name throws NoSuchFieldException or SecurityException.

Parameters:

  • c: class to search
  • name: primary field name
  • name2: fallback field name
Returns: the matching public field

getMethod ​

getMethod(Class<?> c, String name, String name2, Class<?>... parameterTypes): MethodSince1.6.0#
Finds a public method by trying name, then name2 if the first lookup throws NoSuchMethodException or SecurityException.

Parameters:

  • c: class to search
  • name: primary method name
  • name2: fallback method name
  • parameterTypes: exact parameter types
Returns: the matching public method
getMethod(Class<?> c, String name, Class<?>... parameterTypes): MethodSince1.6.0#
Finds a public method by name and exact parameter types.

Parameters:

  • c: class to search
  • name: method name
  • parameterTypes: exact parameter types
Returns: the matching public method

getReflect ​

getReflect(Object obj): ReflectSince1.8.4#
Returns a jOOR reflection wrapper for the object. Wrapper operations can be chained; fields are made accessible when reached. Unlike this library's invocation helpers, the wrapper does not coerce numeric arguments.
const stack = Client.getRegistryManager().getItemStack("minecraft:diamond");
const reflected = Reflection.getReflect(stack.getRaw());
print(`calling through it: ${reflected.call("getCount")}`);
print(`the private count field says ${reflected.field("count").get()}`);

Parameters:

  • obj: the object to wrap
Returns: a reflection wrapper for the object

invokeMethod ​

invokeMethod(Method m, Object c, Object... objects): ObjectSince1.2.3#
Invokes a method, coercing each numeric argument to the corresponding parameter type. Non-numeric arguments are passed through. Pass null as the receiver for a static method. The underlying reflective invocation enforces access and wraps target exceptions in InvocationTargetException.
// a number out of a script is a double, and the coercion makes it fit an int
// parameter anyway. a null receiver means a static method
const Integer = Reflection.getClass("java.lang.Integer");
const bitCount = Reflection.getDeclaredMethod(Integer, "bitCount",
  Reflection.getClass("int"));
print(`the bit count of 3 is ${Reflection.invokeMethod(bitCount, null, 3)}`);

// anything that is not a number is passed through untouched
const ArrayList = Reflection.getClass("java.util.ArrayList");
const list = Reflection.newInstance(ArrayList);
const add = Reflection.getDeclaredMethod(ArrayList, "add",
  Reflection.getClass("java.lang.Object"));
Reflection.invokeMethod(add, list, "diamond");
print(`the list holds ${list.size()}`);

Parameters:

  • m: method to invoke
  • c: receiver, or null for a static method
  • objects: invocation arguments
Returns: the method result, or null for a void method

loadJarFile ​

loadJarFile(String file): booleanSince1.2.6#
Adds a jar from the script's folder to this library's class loader. Its classes can then be resolved through getClass(String) and compilation using that loader. Loading an already-added jar returns true; a missing path throws FileNotFoundException.
const first = Reflection.loadJarFile("libs/mylib.jar");
const second = Reflection.loadJarFile("libs/mylib.jar");
print(`loaded ${first}, and again ${second}`);

const MyThing = Reflection.getClass("com.example.MyThing");
print(`that is ${Reflection.getClassName(MyThing)}`);

Parameters:

  • file: path to the jar, resolved relative to the script's folder
Returns: true if the jar was added or was already loaded

newInstance ​

newInstance(Class<T> c, Object... objects): TSince1.2.7#
Creates an instance using a matching public constructor, coercing numeric arguments if needed. A null argument causes a NullPointerException before constructor lookup.

Parameters:

  • c: class to instantiate
  • objects: constructor arguments

Type Parameters:

  • T: type of instance to construct
Returns: the constructed instance

newInstance0 ​

static newInstance0(Class<T> c, Object... objects): T#
Constructs an instance using a public constructor with exactly matching runtime parameter types, or tries public constructors of the same arity with numeric arguments coerced to their parameter types. If no attempt succeeds, throws a RuntimeException.

Parameters:

  • c: the class to construct
  • objects: constructor arguments

Type Parameters:

  • T: type of instance to construct
Returns: the constructed instance