Is it possible to make a Java program that prints its source code to a new file, and compiles it, and runs the compiled program?
-
6That would get you into an infinite loop :). – jqno Apr 11 '10 at 16:49
-
1Since Java programs can spawn other processes, that seems to be a straightforward combination of a quine and spawning the compiler, then the newly compiled result. – Ben Voigt Apr 11 '10 at 17:00
-
7+1 cause I cant stop thinking about why one would like to do such a thing. – Nils Schmidt Apr 11 '10 at 17:29
-
@TRA no, it suddenly came up from my mind – Ming-Tang Apr 11 '10 at 19:12
9 Answers
Update:
Okay, might as well make it autorun. Enjoy the madness. Run at your own risk.
Yes it's possible, because I actually wrote it up. It doesn't do the RUN part (that's just too crazy, because as others have mentioned, it will cause an infinite loop), but here it is: Quine.java
import java.io.*;
public class Quine {
public static void main(String[] args) throws Exception {
char q = 34;
String out = "Quine$";
String text = (
"import java.io.*; " +
"public class [OUT] { " +
"public static void main(String[] args) throws Exception { " +
"char q = 34; String out = `[OUT]$`; String text = `[TEXT]`; " +
"PrintWriter pw = new PrintWriter(out + `.java`); " +
"pw.format(text, 34, out, text); " +
"pw.close(); Runtime runtime = Runtime.getRuntime(); " +
"runtime.exec(`javac ` + out + `.java`).waitFor(); " +
"runtime.exec(`java ` + out); " +
"} " +
"}"
).replace("`", "%1$c").replace("[OUT]", "%2$s").replace("[TEXT]", "%3$s");
PrintWriter pw = new PrintWriter(out + ".java");
pw.format(text, 34, out, text);
pw.close();
Runtime runtime = Runtime.getRuntime();
runtime.exec("javac " + out + ".java").waitFor();
runtime.exec("java " + out);
}
}
So here's how to get the craziness to start:
javac Quine.java
to compilejava Quine
to run it- It will produce, compile and run
Quine$
- It will produce, compile and run
- I've made sure
Quine.java
is as readable as possible, so the major difference fromQuine$.java
are formatting and the 3xreplace
. The minor difference is thatQuine$.java
hasout
set toQuine$$
. Quine$
will produce, compile and runQuine$$
Quine$$
will produce, compile and runQuine$$$
Quine$$$
will produce, compile and runQuine$$$$
- ...
Do note that this doesn't do any reverse-engineering or cheat by reading the .java
source code, etc. Quine
is a quine-generator because it produces a different code differently formatted, but Quine$
is pretty much a true self-contained quine: it does reproduce itself, it just relabels it Quine$$
(which reproduces itself and relabels to Quine$$$
etc).
So technically there's no infinite loop: it will eventually come to a halt when the file system can't handle another $
. I was able to manually stop the madness by forcefully deleting all Quine$*
files, but run at your own risk!!!

- 376,812
- 128
- 561
- 623
-
I know that it has been a while since this had been posted, but maybe you could make it switch between 2 different file names, then delete the previous – KrystosTheOverlord Apr 12 '19 at 22:52
Yes, it is possible. A trivial implementation would be: have the source code contain itself in a string, save the string to a file and fill its own string with the same string (otherwise, the initial string would be of infinite size, due to the recursive manner of this implementation), compile the file, and run the compiled file (which will, in turn, do the very same).
Non-trivial implementations are significantly harder.

- 8,044
- 33
- 51
-
6"have the source code contain itself in a string" How? Since the string would be part of the source code, this would lead to an infinite string. – sepp2k Apr 11 '10 at 16:53
-
1I edited my post to clarify this. The source code should contain itself in a string, including everythign except the content of this string, which is to be filled at runtime after the source-code was deployed to a text file (before it is being compiled). – M.A. Hanin Apr 11 '10 at 16:56
-
Have a look at my answer and follow the link to rosetta code. There's an example! – Andreas Dolk Apr 11 '10 at 17:29
Sure it works - Have a look at rosetta code and navigate to Quine, which is a self-referential program that can, without any external access, output its own source.
There's one example for a quine in Java.

- 113,398
- 19
- 180
- 268
Programs that reproduces itself or Self Replicating Programs are known as Quine Programs
Sample Program in Java which reproduces itself.
public class QuineProgram {
public static void main(String[] args){
String f = "public class QuineProgram { "
+ "public static void main(String[] args)"
+ "{ String f =%c%s%1$c;"
+ " System.out.printf(f,34,f);}} ";
System.out.printf(f, 34, f);
}
}
Output:
public class QuineProgram { public static void main(String[] args){ String f ="public class QuineProgram { public static void main(String[] args){ String f =%c%s%1$c; System.out.printf(f,34,f);}} "; System.out.printf(f,34,f);}}

- 4,300
- 13
- 44
- 68
You could use the Java Compiler API (JSR-199) for this. Below, code from the JSR-199 that compiles code from a String (slightly modified to make it compile). The code actually compiles source code from the String
into a byte array (i.e. it doesn't write to disk), loads it and then executes it via reflection:
MemoryFileManager.java
: A file manager for compiling strings to byte arrays.ByteArrayClassLoader.java
: A class loader which loads classes from byte arrays.CompileFromString.java
: The class that wrap everything together.
That could be a starting point (credits to Peter Van der Ahé, the original author).
BTW, you need of course a JDK to use this API.

- 562,542
- 136
- 1,062
- 1,124
I don't know exactly what you want, but I think BeanShell is something you can use. BeanShell is an interpreter. You can run uncompiled Java-code (So you give it a String with code and he runs it).
Of course if you really want to do what you wrote, the machine where the program is running needs a JDK to compile your program.
Hope this helps

- 67,591
- 47
- 198
- 287
I dont think it will work in Java. Wouldn't that involve overwriting a running class file.
Suppose your program is in Quine.java compiled to Quine.class.
Now Quine.class will attempt to write its output to Quine.java (so far so good), and compile it to Quine.class. This is gonna be a problem as Quine.class is already running

- 17,454
- 22
- 87
- 114
-
Erm ... he didn't require the new cloned program to be launched in the same VM (from the same classpath). – meriton Apr 11 '10 at 17:59
-
but it will be, as each copy of the program has to be identical, so you cannot change filenames every time – Midhat Apr 11 '10 at 18:02
-
Identical programs need not behave identically. They can use random number generators. They can interact with the host system, e.g. use the first unclaimed file name. – meriton Apr 13 '10 at 23:35
Yes - don't forget to use a JDK instead of a JRE:
Bundle the app's source code files with the app. The app would copy the source files to a new set of source code files, compile the new source files, bundle the new source code with the new class files into a new app, and then spawn the new app.
or
Bundle a decompiler with the app. The app would run the decompiler on its own class files to generate new source code files, compile the new source files, bundle the decompiler with the new class files into a new app, and then spawn the new app.
Here's a Java Quine using preview text block feature (-source 13 --enable-preview) where output is formatted the same as input:
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f ="""
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f =""%c%c%s%1$c"";
System.out.printf(f, 34, 10, f);
}
}
""";
System.out.printf(f, 34, 10, f);
}
}
Output:
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f ="""
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f =""%c%c%s%1$c"";
System.out.printf(f, 34, 10, f);
}
}
""";
System.out.printf(f, 34, 10, f);
}
}
Heavily Commented Version:
package org.sample.quine;
public class Quine
{
public static void main(String...args)
{
// Inside text block use "" followed by token or token followed by "" so that we don't prematurely close text block
String f ="""
package org.sample.quine;
public class Quine
{
public static void main(String...args)
{
// Inside text block use "" followed by token or token followed by "" so that we don't prematurely close text block
String f =""%c%c%s%1$c"";
/* Tokens in template text block, each prefixed with percent symbol
* 1(c) third quote (34) of open block delimiter
* 2(c) new line (10) of open block delimiter
* 3(s) String f text block that goes between two text block delimiters
* 4(1$c) first quote (34) of close block delimiter,
* 1$ means first argument after template argument
* 2$ would be second argument after template argument
*/
// Arguments - 1 template (String f); 2 "; 3 newline; 4 template again without replacing tokens
System.out.printf(f, 34, 10, f);
}
}
""";
/* Tokens in template text block, each prefixed with percent symbol
* 1(c) third quote (34) of open block delimiter
* 2(c) new line (10) of open block delimiter
* 3(s) String f text block that goes between two text block delimiters
* 4(1$c) first quote (34) of close block delimiter,
* 1$ means first argument after template argument
* 2$ would be second argument after template argument
*/
// Arguments - 1 template (String f); 2 "; 3 newline; 4 template again without replacing tokens
System.out.printf(f, 34, 10, f);
}
}

- 456
- 5
- 15