Friday, May 3, 2024
HomeJavaSourceBuddy Compiles Dynamically Created Java Supply Code

SourceBuddy Compiles Dynamically Created Java Supply Code


Two months after the primary commit in October 2022, Peter Verhas, Senior Architect at EPAM Methods, has launched model 2.0.0 of SourceBuddy, a brand new utility that compiles dynamically created Java supply code outlined by a String or a file to a class file. SourceBuddy, requiring Java 17, is a simplified facade for the javac compiler, which delivers the identical performance.

Model 2.0.0 helps a mix of hidden and non-hidden lessons throughout compilation and run-time. Moreover, the API has been simplified, containing breaking modifications equivalent to altering the loadHidden() methodology to the hidden() methodology, therefore the brand new main launch. An entire overview of the modifications per model is on the market within the releases documentation on GitHub.

SourceBuddy can be utilized after including the next Maven dependency:


<dependency>
    <groupId>com.javax0.sourcebuddy</groupId>
    <artifactId>SourceBuddy</artifactId>
    <model>2.0.0</model>
</dependency>

Alternatively the next Gradle dependency could also be used:


implementation 'com.javax0.sourcebuddy:SourceBuddy:2.0.0'

To reveal SourceBuddy, think about the next instance interface which can be utilized by the dynamically created code:


bundle com.app;

public interface PrintInterface {
	void print();
}

The easy API is ready to compile one class at a time by utilizing the static com.javax0.sourcebuddy.Compiler.compile() methodology. For instance, to compile a brand new class implementing the beforehand talked about PrintInterface:


String supply = """
bundle com.app;

public class CustomClass implements PrintInterface {
    @Override
    public void print() {
        System.out.println("Howdy world!");
    }
}""";
Class<?> clazz = Compiler.compile(supply);
PrintInterface customClass = 
    (PrintInterface) clazz.getConstructor().newInstance();
customClass.print();

The fluent API presents options to unravel extra complicated issues such because the compilation of a number of recordsdata with the Compiler.java() static methodology:


Compiler.java().from(supply).compile().load().newInstance(PrintInterface.class);

Optionally, the binary title of the category could also be specified, though SourceBuddy will already detect the title at any time when doable:


.from("com.app", supply)

For a number of supply recordsdata, the from() methodology could also be referred to as a number of occasions, or all of the supply recordsdata in a particular listing could also be loaded without delay:


.from(Paths.get("src/major/java/sourcefiles"))

Optionally, the hidden() methodology could also be used to create a Hidden Class which might’t be used straight by different lessons, solely via reflection by utilizing the category object returned by SourceBuddy.

The compile() methodology generates the byte codes for the Java supply recordsdata, however does not load them into reminiscence but.


last var byteCodes = Compiler.java()
    .from("com.app", supply)
    .compile();

Optionally, the byte codes could also be saved to the native drive:


byteCodes.saveTo(Paths.get("./goal/generated_classes"));

Alternatively, the stream() methodology, which returns a stream of byte arrays, could also be used to retrieve data such because the binary title:


byteCodes.stream().forEach(
    bytecode -> System.out.println(Compiler.getBinaryName(bytecode)));

The byteCodes.load() methodology masses the lessons and converts the bytecode to Class objects:


last var loadedClasses = compiled.load();

Accessing a category is feasible by casting to a superclass or an interface the category implements or by utilizing the reflection API. For instance, to entry the CustomClass:


Class<?> customClass = loadedClasses.get("com.app.CustomClass");

Alternatively, the newInstance() methodology could also be used to create an occasion of the category:


Object customClassInstance = loadedClasses.newInstance("com.app.CustomClass");

The stream of lessons could also be used to retrieve extra details about the lessons:


loadedClasses.stream().forEach(
    clazz -> System.out.println(clazz.getSimpleName()));

Extra details about SourceBuddy may be discovered within the detailed explanations contained in the README file on GitHub.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments