Crear un iniciador EXE de Windows
Al empaquetar puede generar un iniciador nativo de Windows para la aplicación protegida. Es un ejecutable Win32 puro que arranca con un doble clic, de modo que sus usuarios no necesitan instalar Java ni ver nunca run.bat.
El EXE es opcional y no se crea salvo que lo pida. Cuando está activado, el paquete sigue conteniendo run.sh, run.command y run.bat. Ambas formas de arranque usan exactamente la misma estructura de archivo, el mismo classpath, la misma clase principal y las mismas opciones de inicio de la JVM.
1. Ámbito de aplicación
| Tipos de aplicación | Aplicación Java, Spring Boot (los tres diseños), Tomcat |
| Plataformas de destino | windows-x64, windows-x86, windows-aarch64 |
| No admitido | Cifrado de bibliotecas — un único archivo .p4jx no es un directorio de aplicación ejecutable |
Debe seleccionar al menos una plataforma de destino Windows. Puede añadir también destinos Linux y macOS: sus paquetes se generan igualmente, sin EXE, y arrancan con el script habitual. Si no selecciona ningún destino Windows, la tarea falla de inmediato.
2. Cómo hacerlo en la interfaz gráfica
- En la página de archivo de entrada y plataformas de destino, marque Generar un EXE de aplicación para Windows (x64/x86/ARM64) y elija al menos una plataforma Windows.
- La casilla está antes de la bifurcación entre modo simple y avanzado, así que ambos modos pueden generar un EXE.
- Al marcarla se añade una página Iniciador EXE de Windows donde se indican el nombre del archivo, el modo del iniciador, el icono y la información de versión de Windows. Si no la marca, el asistente pasa directamente a la revisión final.
- Con el EXE activado, el campo Opciones de inicio de la JVM solo aparece en esa página del iniciador, para que la misma opción no pueda escribirse en dos sitios. Lo que indique se escribe tanto en el EXE como en los scripts de arranque.
- La página de revisión final enumera las plataformas que realmente recibirán un EXE, junto con los campos del iniciador que haya rellenado.
3. Ejemplos de línea de comandos
La forma mínima solo necesita --windows-exe:
p4j --target-platform windows-x64 javaapp app.jar dist --windows-exe
Indicar el nombre del archivo y el modo de ventana:
p4j --target-platform windows-x64 javaapp app.jar dist \
--windows-exe \
--exe-name MyApp.exe \
--exe-mode gui \
--exe-icon assets/app.ico
Generar las tres arquitecturas de Windows de una vez con los recursos de versión completos:
p4j --target-platform windows-x64,windows-x86,windows-aarch64 \
springboot app.jar dist \
--windows-exe \
--exe-name MyService \
--exe-file-version 1.4.2.0 \
--exe-product-version 1.4.2.0 \
--exe-company 'Example Inc.' \
--exe-product 'Example Service' \
--exe-description 'Example background service' \
--exe-copyright 'Copyright (C) 2026 Example Inc.'
Los paquetes de Tomcat también funcionan; el EXE resultante arranca el Tomcat integrado en primer plano:
p4j --target-platform windows-x64 tomcat app.war dist --context /demo --windows-exe
4. Opciones
| Opción | Descripción |
|---|---|
--windows-exe | Genera un EXE de aplicación para Windows |
--exe-name <name> | Nombre del archivo EXE; por defecto, el del archivo de entrada, o tomcat en los paquetes de Tomcat |
--exe-mode <mode> | console (predeterminado) o gui |
--exe-icon <ico> | Icono de Windows opcional, en formato .ico |
--exe-file-version <a.b.c.d> | Versión de archivo del PE: de uno a cuatro números, cada uno entre 0 y 65535. Vacío equivale a 0.0.0.0 |
--exe-product-version <a.b.c.d> | Versión de producto del PE, con las mismas reglas |
--exe-company <text> | Nombre de la empresa |
--exe-product <text> | Nombre del producto |
--exe-description <text> | Descripción del archivo, visible en el Administrador de tareas y en las propiedades |
--exe-copyright <text> | Aviso de copyright |
Cualquier opción --exe-* activa por sí sola la generación del EXE, así que no hace falta añadir --windows-exe.
El nombre debe ser solo un nombre de archivo, sin /, \ ni componentes de directorio. Si omite el sufijo .exe, se añade automáticamente.
Ambos campos de versión siguen la misma regla: de uno a cuatro números separados por puntos, cada uno entre 0 y 65535, por ejemplo 1.0.0.1. Windows guarda cada parte como un entero sin signo de 16 bits, de modo que se rechazan valores con letras o espacios como v1.0 o 1.0-beta. Un campo vacío significa 0.0.0.0. Ambos se validan antes de empezar el empaquetado, así que los errores aparecen enseguida y no a mitad del proceso.
5. Estructura de la salida
Tomando como ejemplo una aplicación Java, el EXE queda junto a los scripts de arranque en la raíz del paquete:
dist/
├── MyApp.exe # el nuevo iniciador de Windows
├── app.p4jx
├── vlxjre/
├── lib/
├── run.sh
├── run.command
├── run.bat
└── README.md
El README.md del paquete enumera los EXE generados junto con indicaciones sobre la firma de código.
6. Comportamiento del iniciador
El directorio donde está el EXE es la raíz de la aplicación. El iniciador solo acepta rutas de entorno de ejecución, archivo, classpath y directorio de trabajo dentro de esa raíz; todo lo que quede fuera del paquete, y todo lo redirigido mediante un enlace simbólico o una unión, se rechaza y el proceso no arranca. Por tanto puede mover o renombrar el paquete entero sin problema, pero no copiar el EXE por su cuenta.
| Aspecto | Comportamiento |
|---|---|
| Entorno de ejecución | Usa siempre vlxjre\bin\java.exe del propio paquete. Nunca el Java del sistema, y no lee JAVA_HOME. |
| Argumentos de línea de comandos | Los argumentos que reciba el EXE se añaden detrás de los de la propia aplicación. |
| Modo consola | Hereda la entrada y salida estándar de la consola actual, espera a que la aplicación termine y devuelve su código de salida. |
| Modo gráfico | No crea ventana de consola, lo que conviene a las aplicaciones de escritorio. |
| Variables de entorno | Antes de arrancar borra JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS y CLASSPATH, para que nada externo al paquete pueda inyectar opciones de arranque. |
Las opciones de la JVM del EXE quedan fijadas al empaquetar, se firman junto con el bloque de parámetros y se verifican en tiempo de ejecución; no pueden cambiarse una vez desplegado. APP_JAVA_OPTS solo afecta a run.bat: el EXE lo ignora. Para cambiar las opciones de la JVM del EXE, vuelva a empaquetar.
Por la misma razón, -javaagent, -agentlib, -agentpath, -Xbootclasspath y --patch-module no pueden escribirse en las opciones de arranque del EXE. Si los pasa mediante --jvm-option, el empaquetado falla de inmediato.
7. Firma de código
Protector4J no firma el EXE generado ni accede a credenciales de Authenticode. Todas las modificaciones del PE —icono, recursos de versión y opciones de arranque— se hacen durante el empaquetado, así que la firma debe ir al final.
- Termine el empaquetado y compruebe que el EXE arranca correctamente la aplicación.
- Aplique una firma Authenticode con su propio certificado, incluyendo una marca de tiempo RFC3161.
- Verifique la firma con la directiva
/pade Windows.
No modifique el archivo PE después de firmarlo: cualquier cambio invalida la firma. Para cambiar el icono o el número de versión, vuelva a empaquetar y a firmar.
8. Campos del archivo de tarea
El p4j-task.yml exportado usa la versión 2 del formato y guarda estos campos cuando el EXE está activado. Los archivos de tarea en versión 1 se siguen pudiendo leer.
windowsExe: true
exeName: MyApp.exe
exeMode: console
exeIcon: assets/app.ico
exeFileVersion: 1.4.2.0
exeProductVersion: 1.4.2.0
exeCompany: Example Inc.
exeProduct: Example Service
exeDescription: Example background service
exeCopyright: Copyright (C) 2026 Example Inc.
9. Resolución de problemas
| Síntoma | Causa y solución |
|---|---|
| Avisa de que hace falta una plataforma de destino Windows | El EXE está activado pero no se ha elegido windows-x64, windows-x86 ni windows-aarch64. |
| Avisa de un formato de versión no válido | Un campo de versión contiene letras o espacios, tiene más de cuatro partes, o alguna queda fuera de 0–65535. |
| Avisa de que el nombre del EXE debe ser solo un nombre de archivo | El nombre contiene un separador de rutas. Use un nombre sin directorios. |
| Avisa de que no encuentra el archivo de icono | --exe-icon apunta a un .ico que no existe. Revise la ruta. |
| Al hacer doble clic no aparece ninguna ventana y la aplicación se cierra | La aplicación falla al arrancar en modo gráfico. Vuelva a empaquetar en modo consola para ver la salida de error. |
| Un EXE copiado a otro sitio no funciona | El iniciador necesita el entorno de ejecución y el archivo en el mismo directorio del paquete. Copie el directorio de salida completo. |
La lista completa de opciones está en la Referencia de la línea de comandos; el asistente gráfico se describe en la Guía de la interfaz gráfica.