If you are using Java 6, you could try the Java Compiler API. At its core is the JavaCompiler class. You should be able to construct the source code for your Comparator object in memory.

Warning: I have not actually tried the code below as the JavaCompiler object is not available on my platform, for some odd reason...

Warning: Compiling arbitrary Java code can be hazardous to your health.

Consider yourself warned...

String comparableClassName = ...; // the class name of the objects you wish to compare
String comparatorClassName = ...; // something random to avoid class name conflicts
String source = "public class " + comparatorClassName + " implements Comparable<" + comparableClassName + "> {" +
                "    public int compare(" + comparableClassName + " a, " + comparableClassName + " b) {" +
                "        return " + expression + ";" +
                "    }" +
                "}";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

/*
 * Please refer to the JavaCompiler JavaDoc page for examples of the following objects (most of which can remain null)
 */
Writer out = null;
JavaFileManager fileManager = null;
DiagnosticListener<? super JavaFileObject> diagnosticListener = null;
Iterable<String> options = null;
Iterable<String> classes = null;
Iterable<? extends JavaFileObject> compilationUnits = new ArrayList<? extends JavaFileObject>();
compilationUnits.add(
    new SimpleJavaFileObject() {
        // See the JavaDoc page for more details on loading the source String
    }
);

compiler.getTask(out, fileManager, diagnosticListener, options, classes, compilationUnits).call();

Comparator comparator = (Comparator) Class.forName(comparableClassName).newInstance();

After this, you just have to store the appropriate Java expression in your database field, referencing a and b.

Answer from Adam Paynter on Stack Overflow
Top answer
1 of 16
41

If you are using Java 6, you could try the Java Compiler API. At its core is the JavaCompiler class. You should be able to construct the source code for your Comparator object in memory.

Warning: I have not actually tried the code below as the JavaCompiler object is not available on my platform, for some odd reason...

Warning: Compiling arbitrary Java code can be hazardous to your health.

Consider yourself warned...

String comparableClassName = ...; // the class name of the objects you wish to compare
String comparatorClassName = ...; // something random to avoid class name conflicts
String source = "public class " + comparatorClassName + " implements Comparable<" + comparableClassName + "> {" +
                "    public int compare(" + comparableClassName + " a, " + comparableClassName + " b) {" +
                "        return " + expression + ";" +
                "    }" +
                "}";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

/*
 * Please refer to the JavaCompiler JavaDoc page for examples of the following objects (most of which can remain null)
 */
Writer out = null;
JavaFileManager fileManager = null;
DiagnosticListener<? super JavaFileObject> diagnosticListener = null;
Iterable<String> options = null;
Iterable<String> classes = null;
Iterable<? extends JavaFileObject> compilationUnits = new ArrayList<? extends JavaFileObject>();
compilationUnits.add(
    new SimpleJavaFileObject() {
        // See the JavaDoc page for more details on loading the source String
    }
);

compiler.getTask(out, fileManager, diagnosticListener, options, classes, compilationUnits).call();

Comparator comparator = (Comparator) Class.forName(comparableClassName).newInstance();

After this, you just have to store the appropriate Java expression in your database field, referencing a and b.

2 of 16
32

The question of how to programmatically compile Java Code that is given as a String is asked quite frequently and in various forms, sometimes referring to code that is stored in a database or entered by the user. When I searched for information about this, I stumbled upon many of these questions, and was disappointed to see that the general recommendation was to use external tools (BeanShell, Groovy...). The answer by Adam Paynter to this question was the most helpful in order to at least figure out the relevant keywords. But even by consulting further external resources (like an example from Java2s), I struggled with implementing a pure in-memory compilation of one or more Java classes (that actually worked) using only the JavaCompiler API.


So here is an example showing the whole process of compiling one or multiple classes in-memory, at runtime, when their source code is given as a string. It is built around a small utility class, RuntimeCompiler, that simply receives a sequence class names and the corresponding source codes, and then allows compiling these classes and obtaining the Class objects.

It is a MCVE that can be compiled and executed directly - with a JDK, not with a JRE, because the latter does not contain the tools like the JavaCompiler.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
 * An example showing how to use the RuntimeCompiler utility class
 */
public class RuntimeCompilerExample
{
    public static void main(String[] args) throws Exception
    {
        simpleExample();
        twoClassExample();
        useLoadedClassExample();
    }

    /**
     * Simple example: Shows how to add and compile a class, and then
     * invoke a static method on the loaded class.
     */
    private static void simpleExample()
    {
        String classNameA = "ExampleClass";
        String codeA =
            "public class ExampleClass {" + "\n" + 
            "    public static void exampleMethod(String name) {" + "\n" + 
            "        System.out.println(\"Hello, \"+name);" + "\n" + 
            "    }" + "\n" + 
            "}" + "\n";

        RuntimeCompiler r = new RuntimeCompiler();
        r.addClass(classNameA, codeA);
        r.compile();

        MethodInvocationUtils.invokeStaticMethod(
            r.getCompiledClass(classNameA), 
            "exampleMethod", "exampleParameter");
    }

    /**
     * An example showing how to add two classes (where one refers to the 
     * other), compile them, and invoke a static method on one of them
     */
    private static void twoClassExample()
    {
        String classNameA = "ExampleClassA";
        String codeA =
            "public class ExampleClassA {" + "\n" + 
            "    public static void exampleMethodA(String name) {" + "\n" + 
            "        System.out.println(\"Hello, \"+name);" + "\n" + 
            "    }" + "\n" + 
            "}" + "\n";

        String classNameB = "ExampleClassB";
        String codeB =
            "public class ExampleClassB {" + "\n" + 
            "    public static void exampleMethodB(String name) {" + "\n" + 
            "        System.out.println(\"Passing to other class\");" + "\n" + 
            "        ExampleClassA.exampleMethodA(name);" + "\n" + 
            "    }" + "\n" + 
            "}" + "\n";

        RuntimeCompiler r = new RuntimeCompiler();
        r.addClass(classNameA, codeA);
        r.addClass(classNameB, codeB);
        r.compile();

        MethodInvocationUtils.invokeStaticMethod(
            r.getCompiledClass(classNameB), 
            "exampleMethodB", "exampleParameter");
    }

    /**
     * An example that compiles and loads a class, and then uses an 
     * instance of this class
     */
    private static void useLoadedClassExample() throws Exception
    {
        String classNameA = "ExampleComparator";
        String codeA =
            "import java.util.Comparator;" + "\n" + 
            "public class ExampleComparator " + "\n" + 
            "    implements Comparator<Integer> {" + "\n" + 
            "    @Override" + "\n" + 
            "    public int compare(Integer i0, Integer i1) {" + "\n" + 
            "        System.out.println(i0+\" and \"+i1);" + "\n" + 
            "        return Integer.compare(i0, i1);" + "\n" + 
            "    }" + "\n" + 
            "}" + "\n";

        RuntimeCompiler r = new RuntimeCompiler();
        r.addClass(classNameA, codeA);
        r.compile();

        Class<?> c = r.getCompiledClass("ExampleComparator");
        Comparator<Integer> comparator = (Comparator<Integer>) c.newInstance();

        System.out.println("Sorting...");
        List<Integer> list = new ArrayList<Integer>(Arrays.asList(3,1,2));
        Collections.sort(list, comparator);
        System.out.println("Result: "+list);
    }

}


/**
 * Utility class for compiling classes whose source code is given as
 * strings, in-memory, at runtime, using the JavaCompiler tools.
 */
class RuntimeCompiler
{
    /**
     * The Java Compiler
     */
    private final JavaCompiler javaCompiler;

    /**
     * The mapping from fully qualified class names to the class data
     */
    private final Map<String, byte[]> classData;

    /**
     * A class loader that will look up classes in the {@link #classData}
     */
    private final MapClassLoader mapClassLoader;

    /**
     * The JavaFileManager that will handle the compiled classes, and
     * eventually put them into the {@link #classData}
     */
    private final ClassDataFileManager classDataFileManager;

    /**
     * The compilation units for the next compilation task
     */
    private final List<JavaFileObject> compilationUnits;


    /**
     * Creates a new RuntimeCompiler
     * 
     * @throws NullPointerException If no JavaCompiler could be obtained.
     * This is the case when the application was not started with a JDK,
     * but only with a JRE. (More specifically: When the JDK tools are 
     * not in the classpath).
     */
    public RuntimeCompiler()
    {
        this.javaCompiler = ToolProvider.getSystemJavaCompiler();
        if (javaCompiler == null)
        {
            throw new NullPointerException(
                "No JavaCompiler found. Make sure to run this with "
                    + "a JDK, and not only with a JRE");
        }
        this.classData = new LinkedHashMap<String, byte[]>();
        this.mapClassLoader = new MapClassLoader();
        this.classDataFileManager =
            new ClassDataFileManager(
                javaCompiler.getStandardFileManager(null, null, null));
        this.compilationUnits = new ArrayList<JavaFileObject>();
    }

    /**
     * Add a class with the given name and source code to be compiled
     * with the next call to {@link #compile()}
     * 
     * @param className The class name
     * @param code The code of the class
     */
    public void addClass(String className, String code)
    {
        String javaFileName = className + ".java";
        JavaFileObject javaFileObject =
            new MemoryJavaSourceFileObject(javaFileName, code);
        compilationUnits.add(javaFileObject);
    }

    /**
     * Compile all classes that have been added by calling 
     * {@link #addClass(String, String)}
     * 
     * @return Whether the compilation succeeded
     */
    boolean compile()
    {
        DiagnosticCollector<JavaFileObject> diagnosticsCollector =
            new DiagnosticCollector<JavaFileObject>();
        CompilationTask task =
            javaCompiler.getTask(null, classDataFileManager,
                diagnosticsCollector, null, null, 
                compilationUnits);
        boolean success = task.call();
        compilationUnits.clear();
        for (Diagnostic<?> diagnostic : diagnosticsCollector.getDiagnostics())
        {
            System.out.println(
                diagnostic.getKind() + " : " + 
                diagnostic.getMessage(null));
            System.out.println(
                "Line " + diagnostic.getLineNumber() + 
                " of " + diagnostic.getSource());
            System.out.println();
        }
        return success;
    }


    /**
     * Obtain a class that was previously compiled by adding it with
     * {@link #addClass(String, String)} and calling {@link #compile()}. 
     * 
     * @param className The class name
     * @return The class. Returns <code>null</code> if the compilation failed.
     */
    public Class<?> getCompiledClass(String className)
    {
        return mapClassLoader.findClass(className);
    }

    /**
     * In-memory representation of a source JavaFileObject 
     */
    private static final class MemoryJavaSourceFileObject extends
        SimpleJavaFileObject
    {
        /**
         * The source code of the class
         */
        private final String code;

        /**
         * Creates a new in-memory representation of a Java file
         * 
         * @param fileName The file name
         * @param code The source code of the file
         */
        private MemoryJavaSourceFileObject(String fileName, String code)
        {
            super(URI.create("string:///" + fileName), Kind.SOURCE);
            this.code = code;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors)
            throws IOException
        {
            return code;
        }
    }

    /**
     * A class loader that will look up classes in the {@link #classData}
     */
    private class MapClassLoader extends ClassLoader
    {
        @Override
        public Class<?> findClass(String name)
        {
            byte[] b = classData.get(name);
            return defineClass(name, b, 0, b.length);
        }
    }

    /**
     * In-memory representation of a class JavaFileObject
     * @author User
     *
     */
    private class MemoryJavaClassFileObject extends SimpleJavaFileObject
    {
        /**
         * The name of the class represented by the file object
         */
        private final String className;

        /**
         * Create a new java file object that represents the specified class
         * 
         * @param className THe name of the class
         */
        private MemoryJavaClassFileObject(String className)
        {
            super(URI.create("string:///" + className + ".class"), 
                Kind.CLASS);
            this.className = className;
        }

        @Override
        public OutputStream openOutputStream() throws IOException
        {
            return new ClassDataOutputStream(className);
        }
    }


    /**
     * A JavaFileManager that manages the compiled classes by passing
     * them to the {@link #classData} map via a ClassDataOutputStream
     */
    private class ClassDataFileManager extends
        ForwardingJavaFileManager<StandardJavaFileManager>
    {
        /**
         * Create a new file manager that delegates to the given file manager
         * 
         * @param standardJavaFileManager The delegate file manager
         */
        private ClassDataFileManager(
            StandardJavaFileManager standardJavaFileManager)
        {
            super(standardJavaFileManager);
        }

        @Override
        public JavaFileObject getJavaFileForOutput(final Location location,
            final String className, Kind kind, FileObject sibling)
            throws IOException
        {
            return new MemoryJavaClassFileObject(className);
        }
    }


    /**
     * An output stream that is used by the ClassDataFileManager
     * to store the compiled classes in the  {@link #classData} map
     */
    private class ClassDataOutputStream extends OutputStream
    {
        /**
         * The name of the class that the received class data represents
         */
        private final String className;

        /**
         * The output stream that will receive the class data
         */
        private final ByteArrayOutputStream baos;

        /**
         * Creates a new output stream that will store the class
         * data for the class with the given name
         * 
         * @param className The class name
         */
        private ClassDataOutputStream(String className)
        {
            this.className = className;
            this.baos = new ByteArrayOutputStream();
        }

        @Override
        public void write(int b) throws IOException
        {
            baos.write(b);
        }

        @Override
        public void close() throws IOException
        {
            classData.put(className, baos.toByteArray());
            super.close();
        }
    }
}

/**
 * Utility methods not directly related to the RuntimeCompiler
 */
class MethodInvocationUtils
{
    /**
     * Utility method to invoke the first static method in the given 
     * class that can accept the given parameters.
     *  
     * @param c The class
     * @param methodName The method name
     * @param args The arguments for the method call
     * @return The return value of the method call
     * @throws RuntimeException If either the class or a matching method
     * could not be found
     */
    public static Object invokeStaticMethod(
        Class<?> c, String methodName, Object... args)
    {
        Method m = findFirstMatchingStaticMethod(c, methodName, args);
        if (m == null)
        {
            throw new RuntimeException("No matching method found");
        }
        try
        {
            return m.invoke(null, args);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException(e);
        }
        catch (IllegalArgumentException e)
        {
            throw new RuntimeException(e);
        }
        catch (InvocationTargetException e)
        {
            throw new RuntimeException(e);
        }
        catch (SecurityException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * Utility method to find the first static method in the given
     * class that has the given name and can accept the given 
     * arguments. Returns <code>null</code> if no such method 
     * can be found.
     * 
     * @param c The class
     * @param methodName The name of the method 
     * @param args The arguments
     * @return The first matching static method.
     */
    private static Method findFirstMatchingStaticMethod(
        Class<?> c, String methodName, Object ... args)
    {
        Method methods[] = c.getDeclaredMethods();
        for (Method m : methods)
        {
            if (m.getName().equals(methodName) &&
                Modifier.isStatic(m.getModifiers()))
            {
                Class<?>[] parameterTypes = m.getParameterTypes();
                if (areAssignable(parameterTypes, args))
                {
                    return m;
                }
            }
        }
        return null;
    }

    /**
     * Returns whether the given arguments are assignable to the
     * respective types
     * 
     * @param types The types
     * @param args The arguments
     * @return Whether the arguments are assignable
     */
    private static boolean areAssignable(Class<?> types[], Object ...args)
    {
        if (types.length != args.length)
        {
            return false;
        }
        for (int i=0; i<types.length; i++)
        {
            Object arg = args[i];
            Class<?> type = types[i];
            if (arg != null && !type.isAssignableFrom(arg.getClass()))
            {
                return false;
            }
        }
        return true;
    }

}

EDIT In response to the comment:

In order to compile classes that are contained in external JAR files, it should be sufficient to add the JAR to the classpath of the calling application. The JavaCompiler will then pick up this classpath to find classes that it needs for the compilation.

There seems to be some magic involved. At least, I have not figured out the exact mechanisms behind that, just tested it with an example

And a side note: Of course, one could consider literally arbitrary extensions to this class. My goal was to create a simple, standalone, easily copy-and-pastable example that shows the whole process, and may even be "useful" for certain application patterns.

For more sophisticated functionalities, one could consider either extending this class accordingly, or have a look, for example, at the Java-Runtime-Compiler from the OpenHFT project (I stumbled upon this a few weeks after I had written this answer). It basically uses the same techniques internally, but in a somewhat more sophisticated way, and also offers dedicated mechanisms for handling class loaders for external dependencies.

🌐
Coderanch
coderanch.com › t › 725893 › java › convert-strings-executable-Java-code
How can I convert strings to executable Java code with the Java compiler? (Java in General forum at Coderanch)
Therefore the whole NetCDF_writer Class is compile with ComPile Class CodeFromString() where the InMemoryJavaCompiler compile the sourceCode (the whole NetCDF_writer Class in strings). Then the compiler will create a Netcdf_writer Class which is the NetCDF_writer in java code. The Netcdf_writer_Test will execute the NetCDF_writer getDataNc method.
Discussions

Convert strings to executable java code - Oracle Forums
Hey, I'm not sure how easy or hard this is to accomplish, but I am looking for a way to take a string from a JTextField and use it as a control structure for an IF block. For example, the user input... More on forums.oracle.com
🌐 forums.oracle.com
September 29, 2006
convert String to runtime code in java - Stack Overflow
I'm creating a software that would execute custom code line by string SO, is there any method function or whatever you want that can do that : String command="println("the TEST work !!!")"; More on stackoverflow.com
🌐 stackoverflow.com
May 14, 2017
java - How do you run a string as code? - Stack Overflow
Possible Duplicate: Convert String to code I have a program that needs to be able to execute a string as code. For example, I would have a string that reads: public void do(int a, int b){ a++;... More on stackoverflow.com
🌐 stackoverflow.com
Convert a string in code in Java - Stack Overflow
I'm trying to convert a string in code in Java, but i have no idea how to do it or if it is possible. This is my Java code (Measure is an other class I have created) String str= "Measure m = new More on stackoverflow.com
🌐 stackoverflow.com
🌐
javathinking
javathinking.com › blog › convert-string-to-executable-code-java
Convert String to Executable Code in Java — javathinking.com
The Java Compiler API (javax.tools) provides a way to compile Java source code programmatically. You can take a string containing Java source code, compile it, and then load and execute the resulting bytecode.
🌐
Coderanch
coderanch.com › t › 406593 › java › java › you-convert-String-executable-line
can you convert a String into an executable line? (Beginning Java forum at Coderanch)
You would have to scan it with a scanner, eg lex, flex, JFlex, then pass the resultant tokens to a parser eg yacc, bison, byacc, CUP, and set up TACs (triple address codes), or put executable code into the parser. Get yourself a book about compiler design, because that is what you are doing.
🌐
javathinking
javathinking.com › blog › convert-string-to-code-java
Converting String to Code in Java — javathinking.com
In this blog post, we'll explore the core concepts, typical usage scenarios, common pitfalls, and best practices related to converting a string to code in Java. ... Java Reflection allows you to inspect and manipulate classes, methods, fields, etc., at runtime. You can use reflection to create objects, invoke methods, and access fields based on strings that represent class names, method names, etc. The Java Compiler API provides a way to compile Java source code (represented as a string) at runtime. This is useful when you want to generate and execute new Java classes on the fly.
🌐
Baeldung
baeldung.com › home › java › core java › compiling and executing code from a string in java
Compiling and Executing Code From a String in Java | Baeldung
May 23, 2025 - In this tutorial, we’ll learn how to turn a String containing Java source code into a compiled class and execute it.
🌐
Oracle
forums.oracle.com › ords › apexds › post › convert-strings-to-executable-java-code-7474
Convert strings to executable java code - Oracle Forums
September 29, 2006 - Hey, I'm not sure how easy or hard this is to accomplish, but I am looking for a way to take a string from a JTextField and use it as a control structure for an IF block. For example, the user input...
Find elsewhere
🌐
Coderanch
coderanch.com › t › 509424 › java › Execute-java-statement-stored-string
Execute java statement stored in string (Java in General forum at Coderanch)
Example: String a="System.out.println(1)"; Is there any way to execute the command stored in string a so that i can see the output on console? ... Ño you can't. The point is that java needs to be compiled to byte code to be able to be executed.
🌐
javathinking
javathinking.com › blog › convert-string-to-command-java
Convert String to Command in Java — javathinking.com
To convert a string to a command, we typically use ProcessBuilder to build a process based on the command string. The string representing the command may need to be parsed into individual arguments. For example, a command like java -version has two parts: the executable (java) and the argument (-version).
🌐
Stack Overflow
stackoverflow.com › questions › 48484641 › convert-a-string-in-code-in-java
Convert a string in code in Java - Stack Overflow
This is my Java code (Measure is an other class I have created) ... Whatever you write inside a String, will be considered as a value by JVM. ... @Ravi it's clear, OP want to have user dependent value to be used as code at runtime. While that could be dangerous in some way that could, in the same time, be useful. ... Save this answer. ... Show activity on this post. No I dont think that is a good practice, you don't need to do it that way, just instantiate outside of the string, it will be fine and good practice.
🌐
Tek-Tips
tek-tips.com › home › forums › software › programmers › languages › java
String to Executable Code | Tek-Tips
March 28, 2004 - Your going to have to change data types from string to Double or Float here is an example call to change to Double: stringToDouble ... Ok i looked in the java docs, and found none of that. Convert is what type of object. Is there seriously no way to have the java compiler execute a line of code ...
🌐
W3Docs
w3docs.com › java
How can I convert my Java program to an .exe file?
Another option is to use a tool called JSmooth, which is a Java Executable Wrapper that can be used to wrap Java applications as Windows executables.
🌐
Programmersought
programmersought.com › article › 10024887797
Convert java string expressions into executable code - Programmer Sought
<!-- Analyze expression --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-jexl3</artifactId> <version>3.1</version> </dependency> ``` ### java code ```java import org.apache.commons.jexl3.*; import java.util.Map; /** * java converts (string) expressions into executable code * @author Liu Zhixin */ public class EvalTest { /** * java replaces (string to) expressions into executable code * * @param jexlExp expression * @param map * @return */ public static Object convertToCode(String jexlExp, Map<String, Object> map) { // Create or search engine JexlEngine jexl = new Jexl