usr lib jre jdk for change java quine

java - lib - set jdk 8 default ubuntu



Programas que se reproducen. (8)

Los programas que se reproducen a sí mismos o Programas de auto-replicación se conocen como Programas Quine

Programa de muestra en Java que se reproduce a sí mismo.

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); } }

Salida:

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);}}

¿Es posible crear un programa Java que imprima su código fuente en un archivo nuevo, lo compile y ejecute el programa compilado?


Actualizar:

Bien, bien podría hacer que se ejecute automáticamente. Disfruta de la locura. Corre bajo tu propio riesgo.

Sí, es posible, porque en realidad lo escribí. No hace la parte RUN (eso es demasiado loco, porque como han mencionado otros, causará un bucle infinito), pero aquí está: 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); } }

Así que aquí está la manera de comenzar la locura:

  • javac Quine.java para compilar
  • java Quine para ejecutarlo
    • Producirá, compilará y ejecutará Quine$
  • Me he asegurado de que Quine.java sea ​​lo más legible posible, por lo que la principal diferencia con respecto a Quine$.java es el formato y el replace 3x. La pequeña diferencia es que Quine$.java ha establecido en Quine$$ .
  • Quine$ producirá, compilará y ejecutará Quine$$
  • Quine$$ producirá, compilará y ejecutará Quine$$$
  • Quine$$$ producirá, compilará y ejecutará Quine$$$$
  • ...

Tenga en cuenta que esto no hace ingeniería inversa ni engaño al leer el código fuente .java , etc. Quine es un generador de Quine porque produce un código diferente con un formato diferente, pero Quine$ es prácticamente un verdadero autocontenido. quine: se reproduce a sí mismo, simplemente lo reetiqueta a Quine$$ (que se reproduce a sí mismo y reetiqueta a Quine$$$ etc.)

Así que técnicamente no hay un bucle infinito: eventualmente se detendrá cuando el sistema de archivos no pueda manejar otros $ . Pude detener manualmente la locura al eliminar por la fuerza todos los archivos de Quine$* , ¡pero corre a su propio riesgo!


No creo que funcione en Java. ¿Eso no implicaría sobrescribir un archivo de clase en ejecución?

Supongamos que su programa está en Quine.java compilado en Quine.class.

Ahora Quine.class intentará escribir su salida en Quine.java (hasta ahora todo bien), y compilarla en Quine.class. Esto será un problema ya que Quine.class ya se está ejecutando


No sé exactamente lo que quieres, pero creo que BeanShell es algo que puedes usar. BeanShell es un intérprete. Puede ejecutar un código Java no compilado (así que le asigna una cadena con un código y él lo ejecuta).

Por supuesto, si realmente desea hacer lo que escribió, la máquina donde se ejecuta el programa necesita un JDK para compilar su programa.

Espero que esto ayude


Podría usar la API del compilador de Java (JSR-199) para esto. A continuación, el código del JSR-199 que compila el código de una Cadena (ligeramente modificado para que se compile). El código realmente compila el código fuente de la String en una matriz de bytes (es decir, no escribe en el disco), lo carga y luego lo ejecuta a través de la reflexión:

Eso podría ser un punto de partida (créditos para Peter Van der Ahé, el autor original).

Por cierto, necesitas un JDK para usar esta API.


Sí, es posible. Una implementación trivial sería: hacer que el código fuente se contenga en una cadena, guardar la cadena en un archivo y completar su propia cadena con la misma cadena (de lo contrario, la cadena inicial sería de tamaño infinito, debido a la forma recursiva de este implementación), compile el archivo y ejecute el archivo compilado (que, a su vez, hará lo mismo).

Las implementaciones no triviales son significativamente más difíciles.


Sí, no olvide utilizar un JDK en lugar de un JRE:

  1. Agrupe los archivos de código fuente de la aplicación con la aplicación. La aplicación copiaría los archivos de origen en un nuevo conjunto de archivos de código fuente, compilaría los nuevos archivos de origen, agruparía el nuevo código fuente con los nuevos archivos de clase en una nueva aplicación y luego generaría la nueva aplicación.

    o

  2. Agrupa un descompilador con la aplicación. La aplicación ejecutaría el descompilador en sus propios archivos de clase para generar nuevos archivos de código fuente, compilar los nuevos archivos de fuente, agrupar el descompilador con los nuevos archivos de clase en una nueva aplicación y luego generar la nueva aplicación.


Seguro que funciona: eche un vistazo al código rosetta y navegue hasta Quine, que es un programa autorreferencial que puede, sin ningún acceso externo, generar su propia fuente .

Hay un ejemplo para una quine en Java.