Class Java
- All Implemented Interfaces:
ContextProvider, PropertyChangeSource, Rebindable
- Direct Known Subclasses:
DesktopJava
OnTheFlyAgiTool base class.- Author:
- anahata
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionclassSpecialized child-first, hot-reloadingURLClassLoaderused for executing dynamic scripts compiled in memory or via external javac. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected AgiClassLoaderSession-scoped classloader holding in-memory compiled classes and library URLs.protected Map<String, AgiCompiledClass> In-memory compiled classes registered across turns for this AGI session.protected VeryPrettyClassPathPrinterThe transient printer used to generate token-optimized classpath manifests.The base compiler and classloader classpath.A set of infrastructure classes that MUST always be loaded by the parent classloader (the ASI engine) to preserve static state and ThreadLocal context.Fields inherited from class AnahataToolkit
childrenProviders, propertyChangeSupportFields inherited from class ToolContext
toolkit -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddParentFirstClasses(List<String> fqns) Adds a list of class FQNs to the Parent-First ClassLoader guard set, resolving each class on the host classloader and recursively registering its superclasses and interfaces.Clears all compiled classes and sources from the AGI in-memory registry.Class<?> compile(String sourceCode, String className, String extraClassPath, String[] compilerOptions, Path javacPath) Compiles Java source code into a Class object.Compiles one or more modular Java classes into the in-memory classpath of this AGI session without executing them.compileAndExecute(String sourceCode, String extraClassPath, String[] compilerOptions) Convenience overload forcompileAndExecute(String, String, String[], String)using default compiler.compileAndExecute(String sourceCode, String extraClassPath, String[] compilerOptions, String jdk) Compiles and executes a Java class named 'Anahata' on the application's JVM.compileBytecodes(String sourceCode, String classFqn, String extraClassPath, String[] compilerOptions, Path javacPath) Compiles a modular Java class and returns all resulting bytecode byte arrays.compileBytecodes(List<AgiClassSource> sources, String extraClassPath, String[] compilerOptions, Path javacPath) Compiles multiple modular Java classes simultaneously and returns all resulting bytecode byte arrays.Class<?> compileInMemory(String sourceCode, String className, String extraClassPath, String[] compilerOptions, JavaCompiler compiler) Compiles Java source code in memory usingJavaCompiler.compileInMemoryBytecodes(String sourceCode, String classFqn, String extraClassPath, String[] compilerOptions, JavaCompiler compiler) Compiles source code in memory and extracts all generated class bytecode byte arrays.compileInMemoryBytecodes(List<AgiClassSource> sources, String extraClassPath, String[] compilerOptions, JavaCompiler compiler) Compiles multiple source files in memory simultaneously and extracts all generated class bytecode byte arrays.protected Class<?> compileWithExternalJavac(String sourceCode, String className, String extraClassPath, String[] compilerOptions, Path javacPath) Compiles Java source code using an externaljavacprocess and loads the resulting class.protected VeryPrettyClassPathPrinterFactory method to create the specialized classpath printer.protected Java.AnahataClassLoadercreateReloadingClassLoader(List<URL> extraUrls, Map<String, byte[]> compiledClasses) Factory method to create an instance ofJava.AnahataClassLoaderwithAgiClassLoaderas parent.protected byte[]findClassFallbackBytes(String name) A hook for subclasses to provide class bytes if the standard loading flow fails.static PathfindJavacInJdkHome(Path home) Helper to find a javac executable within a candidate JDK home directory.static StringformatInternalMethods(@NonNull Class<?> clazz) Traverses the inheritance hierarchy of a class and formats all declared methods annotated with Internal.getAgiClassSources(List<String> classFqns) Retrieves the stored Java source code for one or more previously compiled AGI classes.Collects all compiled bytecode maps from activeAgiCompiledClassinstances.Gets the list of immediate child context providers.protected final VeryPrettyClassPathPrinterGets the lazily-initialized classpath printer.protected Class<? extends ToolContext> The class the model should extend when generating Agi tools.Gets the current default classpath used for compilation and class loading.protected JavaCompilerOverridable method for implementations to decide what compiler to use by default.protected List<ClassLoader> Hook for subclasses to provide extra/sibling classloaders to search if both the child classpath and the parent classloader fail to find a class.getInternalMethods(String classFqn) Inspects the internal helper and context methods of a target class or hierarchy, describing what each method does and whether it requires a captured ToolContext when called from subthreads.Discovers all known JDK installations on the host environment.Returns the active session-scopedAgiClassLoader, lazily instantiating it from all accumulatedAgiCompiledClasslibrary URLs if not yet created.Returns a token-efficient, pretty-printed version of the default classpath.Gets a list of system instruction strings provided by this context provider.voidPerforms initial setup for a newly created toolkit instance.static voidlogClassloading(String message) Emits a high-salience classloading lifecycle log message.voidpopulateMessage(RagMessage ragMessage) Populates the givenRagMessagewith dynamic, just-in-time context parts.voidCallback method triggered by the Asi Container once the Agi session has been fully deserialized and associated to the ASI container.voidrebind()Rebinds the toolkit after deserialization.final voidRegisters a class and all its superclasses and interfaces to be loaded by the parent classloader.removeAgiClasses(List<String> classFqns) Removes one or more compiled classes from the AGI in-memory registry.voidremoveParentFirstClasses(List<String> fqns) Removes a list of class FQNs from the Parent-First guard set to allow Child-First hot reloading.voidCloses and resets the activeAgiClassLoader.resolveJavacPath(String jdkNameOrPath) Resolves an explicit JDK identifier, name, or path to a javac executable path.voidsetDefaultClasspath(String defaultCompilerClasspath) Sets the default classpath for the compiler and classloader.setProviding(List<String> fqns, boolean providing) Sets whether one or more in-memory compiled classes should have their full source code included in the RAG message.Methods inherited from class AnahataToolkit
getDescription, getId, getName, getParentProvider, getPropertyChangeSupport, isEffectivelyProvidingMethods inherited from class ToolContext
addAttachment, addAttachment, addAttachment, error, error, error, getAgi, getApplicationMap, getAsiContainer, getAsiContainerMap, getCall, getExecutorService, getModelId, getModelMessage, getResourceManager, getResponse, getSessionMap, getThreadSafeLogger, getTool, getToolContext, getToolkit, getToolManager, getTurnMap, isToolExecution, log, peekResponse, runAsyncMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface ContextProvider
getAgi, getContextPosition, getFlattenedHierarchy, getFullyQualifiedId, getHeader, getIconId, getInstructionsTokenCount, getRagTokenCount, isProviding, setParentProvider, setProviding
-
Field Details
-
parentFirstClassess
A set of infrastructure classes that MUST always be loaded by the parent classloader (the ASI engine) to preserve static state and ThreadLocal context. This prevents "Identity Crisis" issues where a child-loaded script cannot access the engine's context. -
defaultCompilerClasspath
The base compiler and classloader classpath. Extra entries can be provided at execution time. This serves as the foundation for both dynamic compilation and the child-first classloader logic. -
classpathPrinter
The transient printer used to generate token-optimized classpath manifests. It is recreated lazily to ensure it is always available after deserialization. -
agiCompiledClasses
In-memory compiled classes registered across turns for this AGI session. -
agiClassLoader
Session-scoped classloader holding in-memory compiled classes and library URLs.
-
-
Constructor Details
-
Java
public Java()Default constructor. Initializes the default classpath from the system's "java.class.path" property.
-
-
Method Details
-
initialize
public void initialize()Performs initial setup for a newly created toolkit instance.This method is called exactly once by the
ToolManagerafter the toolkit has been instantiated and registered. It provides a clean hook for toolkits to perform one-time initialization logic that requires the tool environment to be fully configured, such as scanning for project instructions or registering default resources.Empty implementation as per architectural refinement. Initialization logic is moved to
postActivate()andsetDefaultClasspath(String).- Overrides:
initializein classAnahataToolkit
-
rebind
public void rebind()Description copied from class:AnahataToolkitRebinds the toolkit after deserialization.This method is called by the framework during session activation to restore transient state, reconnect listeners, or refresh cached project instances. It ensures the
propertyChangeSupportis re-initialized.- Specified by:
rebindin interfaceRebindable- Overrides:
rebindin classAnahataToolkit
-
postActivate
public void postActivate()Callback method triggered by the Asi Container once the Agi session has been fully deserialized and associated to the ASI container.Synchronizes the classpath printer with the current default classpath after the toolkit has been activated or deserialized.
- Overrides:
postActivatein classAnahataToolkit
-
getChildrenProviders
Gets the list of immediate child context providers.Dynamically includes all active in-memory
AgiCompiledClassinstances as child context providers.- Specified by:
getChildrenProvidersin interfaceContextProvider- Overrides:
getChildrenProvidersin classAnahataToolkit- Returns:
- The list of children, or an empty list if none.
-
getOrCreateAgiClassLoader
Returns the active session-scopedAgiClassLoader, lazily instantiating it from all accumulatedAgiCompiledClasslibrary URLs if not yet created.- Returns:
- the active
AgiClassLoader.
-
resetAgiClassLoader
public void resetAgiClassLoader()Closes and resets the activeAgiClassLoader. Required when re-compiling or removing classes to allow the JVM to reload redefined classes on the next execution. -
getSystemInstructions
Gets a list of system instruction strings provided by this context provider. These are typically prepended to the conversation as high-level guidance.Provides system instructions for runtime Java code compilation, detailing available methods, multi-threading patterns, memory safety, and JVM properties.
- Returns:
- the list of system instruction blocks.
- Throws:
Exception- if an error occurs while assembling instructions.
-
registerParentFirstClass
Registers a class and all its superclasses and interfaces to be loaded by the parent classloader.- Parameters:
c- The class to register.
-
getConcreteClassModelShouldExtend
The class the model should extend when generating Agi tools.In this base implementation, it returns
OnTheFlyAgiTool, which provides the necessary context anchors (log, error, etc.) for the script.- Returns:
- the base AgiTool class.
-
getDefaultClasspath
Gets the current default classpath used for compilation and class loading.- Returns:
- The full default classpath string.
-
setDefaultClasspath
Sets the default classpath for the compiler and classloader.- Parameters:
defaultCompilerClasspath- The new default classpath string.
-
getPrettyPrintedDefaultClasspath
Returns a token-efficient, pretty-printed version of the default classpath.Implementation note: This leverages lexical grouping and version promotion to keep the classpath manifest small.
- Returns:
- The pretty-printed classpath string.
-
getClasspathPrinter
Gets the lazily-initialized classpath printer.- Returns:
- The
VeryPrettyClassPathPrinterinstance.
-
createClassPathPrinter
Factory method to create the specialized classpath printer.- Returns:
- A new
VeryPrettyClassPathPrinterinstance.
-
populateMessage
Populates the givenRagMessagewith dynamic, just-in-time context parts. These parts are appended to the end of the user's prompt (RAG).Adds session/container map keys, the abbreviated classpath manifest, in-memory compiled classes held by
AgiClassLoader, and available Java compilers and JDKs to the RAG message.- Parameters:
ragMessage- the incoming RAG message to populate.- Throws:
Exception- if an error occurs during message population.
-
addParentFirstClasses
Adds a list of class FQNs to the Parent-First ClassLoader guard set, resolving each class on the host classloader and recursively registering its superclasses and interfaces.- Parameters:
fqns- List of fully qualified class names (FQNs) to resolve and add to parent-first classes.- Throws:
ClassNotFoundException- If any requested class cannot be loaded by the host ClassLoader.
-
removeParentFirstClasses
-
getAllAgiCompiledBytecodes
Collects all compiled bytecode maps from activeAgiCompiledClassinstances.- Returns:
- map of binary class name to compiled bytecode byte array.
-
getInternalMethods
Inspects the internal helper and context methods of a target class or hierarchy, describing what each method does and whether it requires a captured ToolContext when called from subthreads.- Parameters:
classFqn- The fully qualified name of the class to inspect.- Returns:
- Formatted Markdown summary of the class hierarchy and its annotated internal methods.
- Throws:
Exception- If the class cannot be found.
-
formatInternalMethods
-
logClassloading
Emits a high-salience classloading lifecycle log message.If called within an active tool execution thread, it logs directly to the active
JavaMethodToolResponseso the AI model and developer see classloader events live in the tool response. If called outside a tool execution thread, it logs to SLF4J at INFO level.- Parameters:
message- the classloading log message.
-
createReloadingClassLoader
protected Java.AnahataClassLoader createReloadingClassLoader(List<URL> extraUrls, Map<String, byte[]> compiledClasses) Factory method to create an instance ofJava.AnahataClassLoaderwithAgiClassLoaderas parent.- Parameters:
extraUrls- extra URLs to search child-first.compiledClasses- in-memory compiled bytecode map.- Returns:
- a new
Java.AnahataClassLoader.
-
getKnownJdks
Discovers all known JDK installations on the host environment.Scans: 1. The currently running JVM (via
System.getProperty("java.home")). 2. TheJAVA_HOMEenvironment variable. 3. Standard platform JDK directories (/usr/lib/jvm, /Library/Java/JavaVirtualMachines, C:\Program Files\Java, etc.). 4. Thejavacexecutable available on the systemPATH.Subclasses (such as
NbJavaandIntellijJava) override this method to add IDE-registered platforms and project SDKs.- Returns:
- a list of discovered
KnownJdkinstances.
-
findJavacInJdkHome
-
resolveJavacPath
Resolves an explicit JDK identifier, name, or path to a javac executable path.- Parameters:
jdkNameOrPath- optional name, ID, directory, or direct javac executable path.- Returns:
- the resolved Path to javac, or null if null/empty string provided.
- Throws:
AgiToolException- if an explicit identifier or path was specified but could not be found.
-
compile
public Class<?> compile(String sourceCode, String className, String extraClassPath, String[] compilerOptions, Path javacPath) throws Exception Compiles Java source code into a Class object.Resolution order: 1. If an explicit
javacPathis provided, compiles externally using that binary. 2. IfjavacPathis null and in-memoryJavaCompileris available, compiles in memory. 3. IfjavacPathis null and in-memory compiler is NOT available (JRE/JBR), automatically falls back to the first available JDK javac fromgetKnownJdks().- Parameters:
sourceCode- the Java source code to compile.className- the simple or fully qualified name of the class.extraClassPath- additional classpath entries to include.compilerOptions- additional options for the compiler.javacPath- optional explicit path to a javac executable.- Returns:
- the compiled Class object.
- Throws:
Exception- if compilation or classloading fails.
-
compileInMemory
public Class<?> compileInMemory(String sourceCode, String className, String extraClassPath, String[] compilerOptions, JavaCompiler compiler) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException Compiles Java source code in memory usingJavaCompiler.- Parameters:
sourceCode- the Java source code to compile.className- the fully qualified name of the class.extraClassPath- additional classpath entries to include.compilerOptions- additional options for the Java compiler.compiler- the compiler instance.- Returns:
- the compiled Class object.
- Throws:
ClassNotFoundException- if class not found.NoSuchMethodException- if method not found.IllegalAccessException- if access denied.InvocationTargetException- if invocation fails.
-
compileWithExternalJavac
protected Class<?> compileWithExternalJavac(String sourceCode, String className, String extraClassPath, String[] compilerOptions, Path javacPath) throws Exception Compiles Java source code using an externaljavacprocess and loads the resulting class.Robust implementation: 1. Writes all compiler options to an
@argfileto completely bypass OS/Windows command-line length limits. 2. Enforces matching--releasebytecode compatibility to avoid UnsupportedClassVersionError. 3. Performs atomic cleanup of the scratch directory in a finally block (zero disk leaks).- Parameters:
sourceCode- the Java source code.className- the simple class name.extraClassPath- optional additional classpath entries.compilerOptions- optional compiler options.javacPath- the absolute path to the javac executable.- Returns:
- the loaded
Class. - Throws:
Exception- on compilation or classloading failure.
-
findClassFallbackBytes
A hook for subclasses to provide class bytes if the standard loading flow fails.This is used by the NetBeans implementation (NbJava) to bridge Multi-Release JAR classes into the memory-based loader.
- Parameters:
name- The FQN of the class.- Returns:
- The class bytes, or null if not found.
-
getExtraClassLoaders
Hook for subclasses to provide extra/sibling classloaders to search if both the child classpath and the parent classloader fail to find a class.- Returns:
- A list of additional ClassLoaders to query.
-
compileAndExecute
public Object compileAndExecute(String sourceCode, String extraClassPath, String[] compilerOptions, String jdk) throws Exception Compiles and executes a Java class named 'Anahata' on the application's JVM. The class must extendOnTheFlyAgiTooland implementCallable.- Parameters:
sourceCode- The Java source code to compile and execute.extraClassPath- Additional classpath entries.compilerOptions- Additional compiler options.jdk- Optional JDK name, ID, or path to a javac executable.- Returns:
- The result of the execution.
- Throws:
Exception- if compilation or execution fails.
-
compileAndExecute
public Object compileAndExecute(String sourceCode, String extraClassPath, String[] compilerOptions) throws Exception Convenience overload forcompileAndExecute(String, String, String[], String)using default compiler.- Parameters:
sourceCode- the source code.extraClassPath- additional classpath.compilerOptions- compiler options.- Returns:
- the execution result.
- Throws:
Exception- on error.
-
getDefaultJavaCompiler
Overridable method for implementations to decide what compiler to use by default.- Returns:
ToolProvider.getSystemJavaCompiler();
-
compileInMemoryBytecodes
public Map<String,byte[]> compileInMemoryBytecodes(String sourceCode, String classFqn, String extraClassPath, String[] compilerOptions, JavaCompiler compiler) throws Exception Compiles source code in memory and extracts all generated class bytecode byte arrays.- Parameters:
sourceCode- the Java source code.classFqn- the class fully qualified name.extraClassPath- optional extra classpath.compilerOptions- optional compiler options.compiler- the JavaCompiler instance.- Returns:
- map of class binary names to compiled byte arrays.
- Throws:
Exception- on compilation error.
-
compileInMemoryBytecodes
public Map<String,byte[]> compileInMemoryBytecodes(List<AgiClassSource> sources, String extraClassPath, String[] compilerOptions, JavaCompiler compiler) throws Exception Compiles multiple source files in memory simultaneously and extracts all generated class bytecode byte arrays.- Parameters:
sources- the list of source descriptors.extraClassPath- optional extra classpath.compilerOptions- optional compiler options.compiler- the JavaCompiler instance.- Returns:
- map of class binary names to compiled byte arrays.
- Throws:
Exception- on compilation error.
-
compileBytecodes
public Map<String,byte[]> compileBytecodes(String sourceCode, String classFqn, String extraClassPath, String[] compilerOptions, Path javacPath) throws Exception Compiles a modular Java class and returns all resulting bytecode byte arrays.- Parameters:
sourceCode- the Java source code.classFqn- the class fully qualified name.extraClassPath- optional extra classpath.compilerOptions- optional compiler options.javacPath- optional path to javac executable.- Returns:
- map of class binary names to compiled byte arrays.
- Throws:
Exception- on error.
-
compileBytecodes
public Map<String,byte[]> compileBytecodes(List<AgiClassSource> sources, String extraClassPath, String[] compilerOptions, Path javacPath) throws Exception Compiles multiple modular Java classes simultaneously and returns all resulting bytecode byte arrays.- Parameters:
sources- the list of source descriptors.extraClassPath- optional extra classpath.compilerOptions- optional compiler options.javacPath- optional path to javac executable.- Returns:
- map of class binary names to compiled byte arrays.
- Throws:
Exception- on error.
-
compile
public String compile(List<AgiClassSource> sources, String extraClassPath, String[] compilerOptions, String jdk) throws Exception Compiles one or more modular Java classes into the in-memory classpath of this AGI session without executing them.The compiled classes are registered in the session's RAM and automatically included in the RAG message as context providers. Passing multiple sources compiles them simultaneously, allowing mutual or circular dependencies (e.g. Class A references Class B and Class B references Class A).
- Parameters:
sources- List of Java class source descriptors (each containing fqn and sourceCode).extraClassPath- Optional extra classpath entries separated by File.pathSeparator.compilerOptions- Optional compiler options.jdk- Optional JDK name (from Available JDKs) or explicit path to javac binary.- Returns:
- Confirmation message with compilation summary.
- Throws:
Exception- on compilation error.
-
setProviding
Sets whether one or more in-memory compiled classes should have their full source code included in the RAG message.- Parameters:
fqns- List of class fully qualified names to update providing status for.providing- Whether to include the source code in the RAG message.- Returns:
- Confirmation message.
-
getAgiClassSources
Retrieves the stored Java source code for one or more previously compiled AGI classes. If a requested class is already providing its source code in the RAG message, an error is logged and an informative notice is returned instead to avoid prompt token duplication.- Parameters:
classFqns- List of class fully qualified names to retrieve source code for.- Returns:
- Map of class FQN to its Java source code.
-
removeAgiClasses
-
clearAllAgiClasses
Clears all compiled classes and sources from the AGI in-memory registry.- Returns:
- Confirmation message.
-

