JavaRush /Blog Java /Random-ES /Compilando en Java

Compilando en Java

Publicado en el grupo Random-ES
Programar en un IDE es excelente: coherencia de las dependencias del código, depuración conveniente, pruebas claras, tema oscuro. Entonces, gracias al IDE, el desarrollo avanza a pasos agigantados. Pero ella se relaja. Todos los días, al sumergirse en la funcionalidad del IDE, el desarrollador se acostumbra a comprometerse con un botón o construir con dos clics. Compilando en Java - 1La situación es mucho peor para aquellos nuevos en programación que trabajan en el IDE desde el principio, ignorando el trabajo en la línea de comando. Por ejemplo, en Intellij IDEA, la compilación de una aplicación Java se demuestra mediante una barra de carga en el panel inferior, y todos los parámetros de compilación, el procesamiento de classpath y otras delicias de la vida de Java permanecen detrás de escena. Sugerimos hablar sobre compilar en Java sin un IDE. Para ejecutar los ejemplos de este artículo, asegúrese de que JDK 1.7 o posterior esté instalado en su máquina.

¿Cómo compilar un programa?

La compilación en programación es la reducción del código fuente a código de bytes para el posterior inicio del programa. La secuencia de acciones desde el código fuente hasta el inicio del programa se ve así:
  1. Hay código fuente en un archivo llamado ClassName.java;
  2. Si no hay errores en el código, se compila en código de bytes (en el archivo ClassName.class);
  3. El programa comienza.
Normalmente, cada programa está contenido en un directorio independiente. Como ejemplo simple, llevemos la salida a la consola:
class Test {
   public static void main(String[] args) {
      System.out.println("Это говорит приложение из командной строки");
   }
}

¿Para qué se utiliza el comando javac?

Bien, el primer punto está hecho. Vayamos más allá para entender: ¿cómo compilar? :) El comando javac nos ayudará con esto, cuyo argumento debe especificar el archivo requerido:

javac Test.java
Si no hay errores en el código, aparecerá un archivo Test.class junto al archivo Test.java. Este es el código de bytes compilado. Ahora hay que ponerlo en marcha. Aquí usamos el comando java, que ejecuta el código de bytes: Compilando en Java - 2La captura de pantalla muestra que obtenemos algunos jeroglíficos en la salida: obviamente, esta es una codificación rota. Normalmente esto sucede en un sistema Windows. Para mostrar correctamente el alfabeto cirílico en la consola, existen los siguientes comandos:

REM change CHCP to UTF-8
CHCP 65001
CLS
Cambian la página de códigos de shell actual mientras dure la ventana actual. Intentemoslo de nuevo:

D:\Java>java Test
Esto es lo que dice la aplicación desde la línea de comando. Saber cómo funciona el comando javac es muy útil, ya que este comando es la base de cualquier sistema de construcción de proyectos.

Compilación y ejecución de varias clases

Para trabajar con varias clases necesitas un classpath. Es similar a un sistema de archivos en el que se contienen clases y los paquetes actúan como carpetas. En este punto, vale la pena pensar en separar los archivos de código fuente de los archivos compilados. Como regla general, las fuentes se encuentran en el directorio src y las clases compiladas en bin. Por ejemplo, tenemos una clase Boxy una clase BoxMachineque contiene un método main. Clase Box:
package src;

public class Box {
   private double size;

   public Box(double size) {
       this.size = size;
   }

   public String toString() {
       return "Box have size " + size;
   }
}
Está en el paquete src y necesita ser arreglado. Clase BoxMachine:
package src;

public class BoxMachine {
   public static void main(String[] args) {
       for(int  i = 0; i < 5; i++) {
           System.out.println(new Box(Math.random()*10));
       }
   }
}
Esta clase también se encuentra en el paquete src. En el método main, crea cinco objetos de clase Boxde diferentes tamaños y muestra información sobre ellos en la consola. Para compilar este grupo de clases, debes usar el comando javac del directorio principal (que contiene las carpetas src y bin) con los argumentos:

javac -d bin ./src/*
-d— una bandera después de la cual debes indicar la ubicación donde irán las clases compiladas. Esto es muy conveniente, ya que transferir, por ejemplo, 1000 clases es un proceso que requiere mucha mano de obra. bin- nombre de la carpeta. ./src/*— ubicación de los archivos fuente. *indica que todos los archivos deben compilarse. Ahora las clases compiladas aparecen en la carpeta bin. Para ejecutarlos utilice el comando java del mismo directorio, también con argumentos:

java -classpath ./bin BoxMachine
-classpath— una bandera después de la cual debes indicar la ubicación de las clases compiladas. Java buscará la clase principal y todas las relacionadas en este directorio. ./bin— el nombre de la carpeta en la que se encuentran las clases compiladas. BoxMachine— nombre de la clase principal. Como en el primer caso, no se debe especificar .class, ya que este es el nombre de una clase, no de un archivo. Conclusión:

D:\Java>java -classpath ./bin src.BoxMachine
Box have size 4.085985295359718
Box have size 8.63682158248986
Box have size 6.027448124299726
Box have size 7.288317703877914
Box have size 1.106181659384694

Crear archivos JAR

Para que el programa sea fácil de portar y ejecutar, puede recopilar las clases compiladas en un archivo jar: un archivo de clases. La principal diferencia con los archivos zip o rar es la presencia de un archivo de manifiesto. Este manifiesto especifica la clase principal que se ejecutará cuando se ejecute el archivo jar, la ruta de clase y mucha información adicional. Creemos un archivo manifest.mf en el directorio principal. Su contenido será el siguiente:

main-class: src.BoxMachine
class-path: bin/
main-classespecifica la clase que contiene el método mainy se ejecutará al inicio. class-path— ruta a clases compiladas o bibliotecas adicionales. Ahora es el momento de crear un programa real sin un IDE usando el comando jar:

jar -cmf manifest.mf box-machine.jar  -C bin .
-cmf— una bandera después de la cual debes especificar la ruta al archivo de manifiesto. manifest.mf- camino al manifiesto. box-machine.jar— nombre del archivo jar de salida. — una bandera tras la cual se indica la ruta a las clases compiladas. .— la ruta donde se colocará el archivo jar. En nuestro caso, este es el directorio principal. Ahora puedes lanzar. El lanzamiento de archivos jar también se realiza mediante el comando java, pero luego debe especificar la bandera -jar: indica que el archivo Jar se está iniciando y el segundo argumento es la ruta al jararchivo, incluida la extensión :

java -jar box-machine.jar
Conclusión:

Box have size 5.5495235762547965
Box have size 9.695870044165662
Box have size 2.3408385788129227
Box have size 7.2790741216674135
Box have size 2.3620854470160513

Compilación en Java sin un IDE: descripción general de los sistemas de compilación

A pesar de la relativa facilidad de uso de la línea de comandos, es muy difícil crear proyectos medianos y grandes con ella. Esto lleva mucho tiempo y está plagado de errores de diversos grados. Afortunadamente, existen sistemas de montaje que facilitan mucho el proceso de trabajo. Con varios equipos, este sistema puede montar un proyecto de cualquier complejidad, y la abundancia de complementos creados durante la existencia de dichos sistemas puede eliminar casi cualquier dolor de cabeza.

¿Cómo compilar Java?

Los sistemas de compilación de Java más famosos son Ant, Maven y Gradle. No hay buenos ni malos: cada uno de ellos está creado para solucionar determinados problemas. Veamos cada uno de ellos con más detalle.

Hormiga

Ant es una herramienta de compilación que utiliza un script descrito mediante un archivo xml. estructura del archivo xml:
<?xml version="1.0"?>
<project name="NombreПроекта" default="сценарийПоУмолчанию">
    <target name="NombreСценария">
  //  Действия сценария
        <echo>Hello, World!</echo>
    </target>
  //  Второй сценарий
  //  И тд
</project>
Creemos un archivo build.xml en el directorio principal con el siguiente contenido:
<?xml version="1.0"?>
<project name="BoxMachine" default="test">
   <target name="test">
       <echo>First build in Ant!</echo>
   </target>
</project>
En el mismo directorio, llame al comando ant:

D:\Java>D:\Temp\ant\bin\ant
Buildfile: D:\Java\build.xml

test:
     [echo] First build in Ant!

BUILD SUCCESSFUL
Total time: 0 seconds
La etiqueta <target>puede especificar varias tareas que le permiten administrar el ensamblado y el sistema de archivos. Ant tiene más de 150 comandos disponibles, que se enumeran en la documentación. En el siguiente ejemplo utilizamos sólo 5:
  • mkdir - crear directorios
  • delete- eliminar archivos y directorios
  • javac- Compilación de código Java
  • java- ejecutando código compilado
Así es como se ve un script simple de compilación, compilación o limpieza:
<?xml version="1.0"?>
<project name="BoxMachine" default="compile">
   <target name="compile">
       <mkdir dir="result/classes"/>
       <javac destdir="result/classes" includeantruntime="false">
           <src path="src"/>
       </javac>
   </target>
   <target name="run" depends="compile">
       <java classname="BoxMachine" classpath="result/classes"/>
   </target>
   <target name="clean">
       <delete dir="result"/>
   </target>
</project>
El script describe tres acciones: compile, ,código>ejecutar y clean. compilecrea un directorio de resultados con clases en él, luego usa javac para compilar las clases en el directorio creado. runejecuta las clases compiladas con el comando java. cleanelimina el directorio de resultados. Si ejecuta el comando ant sin argumentos en el directorio principal, se ejecutará la acción de compilación. Si es necesario realizar una acción específica, se especifica en el argumento.

D:\Java>D:/Temp/ant/bin/ant compile
Buildfile: D:\Java\build.xml

compile:
    [mkdir] Created dir: D:\Java\result\classes
    [javac] Compiling 2 source files to D:\Java\result\classes

BUILD SUCCESSFUL
Total time: 1 second

experto

Maven ofrece un enfoque ligeramente diferente a los proyectos de construcción. Aquí, el desarrollador más bien describe su proyecto y las herramientas adicionales que utiliza, a diferencia de Ant, donde la construcción es una secuencia de acciones. Maven es popular entre los desarrolladores debido a su sencilla gestión de dependencias y su conveniente integración con todos los entornos de desarrollo. Cuando trabajamos con Maven, nos adherimos a la siguiente estructura del proyecto: Compilando en Java - 3las reglas de compilación, las dependencias, etc. se describen en el archivo pom.xml. Normalmente se encuentra en la carpeta principal del proyecto. Al iniciar, Maven verifica la estructura y la sintaxis del archivo y le advierte sobre errores. En el directorio principal, junto a las carpetas bin y src, cree un archivo pom.xml y agregue dentro:
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>ru.javarush.testmaven</groupId>
  <artifactId>testMavenWithoutIde</artifactId>
  <version>1.0.0</version>

  <build>
     <defaultGoal>compile</defaultGoal>
     <sourceDirectory>src</sourceDirectory>
     <outputDirectory>bin</outputDirectory>
     <finalName>${project.artifactId}-${project.version}</finalName>
  </build>
</project>
A continuación, ejecute el comando mvn en la línea de comando:

D:\Java>mvn
[INFO] Scanning for projects...
[INFO]
[INFO] -------------< ru.javarush.testmaven:testMavenWithoutIde >--------------
[INFO] Building testMavenWithoutIde 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ testMavenWithoutIde ---
[WARNING] Using platform encoding (Cp1251 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Java\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ testMavenWithoutIde ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding Cp1251, i.e. build is platform dependent!
[INFO] Compiling 2 source files to D:\Java\bin
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.521 s
[INFO] Finished at: 2019-06-25T20:18:05+03:00
[INFO] ------------------------------------------------------------------------
Ahora hay una carpeta src en la carpeta bin donde se encuentran las clases compiladas. En pom.xml, la etiqueta de compilación define el propósito de la compilación: compilación, los directorios del código fuente y los archivos de resultados de la compilación, así como el nombre del proyecto. Maven tiene una variedad de objetivos de compilación y complementos para ejecutar pruebas, crear archivos Jar, crear distribuciones y otras tareas.

Gradle

Este es el sistema de compilación más joven, basado en Ant y Maven. La principal diferencia es que funciona sobre la base de un gráfico acíclico para determinar el orden de las tareas. Esto es muy útil para tareas más complejas, como compilaciones incrementales y de múltiples proyectos. Al compilar con Gradle, también se recomienda ceñirse a la estructura de carpetas del proyecto Maven. Por cierto, el archivo para construir en Gradle se llama build.gradle y parece mucho más pequeño que el de Maven. Ejemplo para nuestras clases:
apply plugin: 'java'
apply plugin: 'application'

sourceSets {
   main {
       java {
           srcDirs 'src'
       }
   }
}
sourceSets.main.output.classesDir = file("bin")

mainClassName = "src.BoxMachine"

defaultTasks 'compileJava', 'run'
El archivo incluye complementos, define el directorio de archivos de código fuente (si no se utiliza la estructura del proyecto Maven), el directorio de resultados de compilación, el nombre de la clase principal y las tareas predeterminadas. El comando gradle en el directorio donde se encuentra el archivo build.gradle es responsable de iniciar la compilación:

d:\Java>D:\Temp\gradle\bin\gradle

Welcome to Gradle 5.4.1!

Here are the highlights of this release:
 - Run builds with JDK12
 - New API for Incremental Tasks
 - Updates to native projects, including Swift 5 support

For more details see https://docs.gradle.org/5.4.1/release-notes.html

Starting a Gradle Daemon (subsequent builds will be faster)

> Task :help

Welcome to Gradle 5.4.1.

To run a build, run gradle <task> ...

To see a list of available tasks, run gradle tasks

To see a list of command-line options, run gradle --help

To see more detail about a task, run gradle help --task <task>

For troubleshooting, visit https://help.gradle.org

BUILD SUCCESSFUL in 52s
1 actionable task: 1 executed

Conclusión

A primera vista, la capacidad de compilar y ensamblar código sin un IDE parece inútil. De hecho, ¿por qué molestarse con las líneas de comando y buscar en Google todos los comandos cuando hay un IDE cómodo con complementos, verificación automática de todo lo posible (los IDE modernos no verifican el nivel de coeficiente intelectual) e integración con sistemas populares? Sin embargo, la práctica demuestra que la capacidad de ensamblar código sin un entorno de desarrollo y comprender cada paso de este proceso es una necesidad imperiosa. Esta habilidad le ahorrará muchas células nerviosas y tiempo a usted y a su empresa. Puede aprender a utilizar el IDE, practicar la escritura de código y, por supuesto, obtener los fundamentos de la programación Java aquí, en JavaRush. Es hora de volver a aprender :)
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION