Criar um iniciador EXE do Windows
Ao empacotar, você pode mandar gerar um iniciador nativo do Windows para o aplicativo protegido. É um executável Win32 puro que abre com dois cliques, de modo que seus usuários não precisam instalar o Java nem lidar com o run.bat.
O EXE é opcional e só é criado quando pedido. Com ele ativado, o pacote continua trazendo run.sh, run.command e run.bat. As duas formas de inicialização usam exatamente a mesma estrutura de arquivo, o mesmo classpath, a mesma classe principal e as mesmas opções de inicialização da JVM.
1. Onde se aplica
| Tipos de aplicativo | Aplicação Java, Spring Boot (as três disposições), Tomcat |
| Plataformas-alvo | windows-x64, windows-x86, windows-aarch64 |
| Sem suporte | Criptografia de bibliotecas — um único arquivo .p4jx não é uma pasta de aplicativo executável |
É preciso marcar pelo menos uma plataforma-alvo Windows. Incluir também alvos Linux e macOS não é problema: os pacotes deles são gerados normalmente, sem EXE, e iniciam pelo script de sempre. Se nenhum alvo Windows for marcado, a tarefa falha na hora.
2. Pela interface gráfica
- Na página do arquivo de entrada e das plataformas-alvo, marque Gerar um EXE de aplicação para Windows (x64/x86/ARM64) e escolha pelo menos uma plataforma Windows.
- Essa caixa fica antes da bifurcação entre modo simples e avançado, então ambos podem gerar um EXE.
- Ao marcá-la, surge uma página Iniciador EXE do Windows onde você informa o nome do arquivo, o modo do iniciador, o ícone e as informações de versão do Windows. Sem marcá-la, o assistente vai direto para a página final.
- Com o EXE ativado, o campo Opções de inicialização JVM aparece só nessa página do iniciador, para que a mesma opção não possa ser digitada em dois lugares. O que você informar é gravado tanto no EXE quanto nos scripts de inicialização.
- A página final lista as plataformas que de fato receberão um EXE, junto com os campos do iniciador que você preencheu.
3. Exemplos de linha de comando
A forma mínima precisa apenas de --windows-exe:
p4j --target-platform windows-x64 javaapp app.jar dist --windows-exe
Definir o nome do arquivo e o modo de janela:
p4j --target-platform windows-x64 javaapp app.jar dist \
--windows-exe \
--exe-name MyApp.exe \
--exe-mode gui \
--exe-icon assets/app.ico
Gerar as três arquiteturas do Windows de uma vez, com os recursos de versão 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.'
Os pacotes do Tomcat também funcionam; o EXE gerado sobe o Tomcat embutido em primeiro plano:
p4j --target-platform windows-x64 tomcat app.war dist --context /demo --windows-exe
4. Opções
| Opção | Descrição |
|---|---|
--windows-exe | Gera um EXE de aplicação para Windows |
--exe-name <name> | Nome do arquivo EXE; por padrão o do arquivo de entrada, ou tomcat nos pacotes do Tomcat |
--exe-mode <mode> | console (padrão) ou gui |
--exe-icon <ico> | Ícone do Windows opcional, no formato .ico |
--exe-file-version <a.b.c.d> | Versão de arquivo do PE: de um a quatro números, cada um entre 0 e 65535. Em branco equivale a 0.0.0.0 |
--exe-product-version <a.b.c.d> | Versão de produto do PE, com as mesmas regras |
--exe-company <text> | Nome da empresa |
--exe-product <text> | Nome do produto |
--exe-description <text> | Descrição do arquivo, visível no Gerenciador de Tarefas e nas propriedades |
--exe-copyright <text> | Aviso de direitos autorais |
Qualquer opção --exe-* já ativa a geração do EXE por si só, então não é preciso acrescentar --windows-exe.
O nome tem de ser só um nome de arquivo, sem /, \ nem componente de pasta. Se você omitir o sufixo .exe, ele é acrescentado.
Os dois campos de versão seguem a mesma regra: de um a quatro números separados por pontos, cada um entre 0 e 65535, por exemplo 1.0.0.1. O Windows guarda cada parte como um inteiro sem sinal de 16 bits, de modo que valores com letras ou espaços, como v1.0 ou 1.0-beta, são recusados. Um campo em branco significa 0.0.0.0. Ambos são validados antes de o empacotamento começar, então um erro aparece de imediato e não no meio do processo.
5. Estrutura da saída
Tomando um aplicativo Java como exemplo, o EXE fica na raiz do pacote, ao lado dos scripts de inicialização:
dist/
├── MyApp.exe # o novo iniciador do Windows
├── app.p4jx
├── vlxjre/
├── lib/
├── run.sh
├── run.command
├── run.bat
└── README.md
O README.md do pacote lista os EXE gerados e traz observações sobre a assinatura de código.
6. Como o iniciador se comporta
A pasta onde está o EXE é a raiz do aplicativo. O iniciador só aceita caminhos de tempo de execução, arquivo, classpath e pasta de trabalho dentro dessa raiz; tudo que estiver fora do pacote, e tudo que for desviado por um link simbólico ou junção, é recusado e o processo não inicia. Você pode, portanto, mover ou renomear o pacote inteiro, mas não copiar o EXE sozinho.
| Aspecto | Comportamento |
|---|---|
| Tempo de execução | Usa sempre o vlxjre\bin\java.exe do pacote. Nunca o Java do sistema, e não lê JAVA_HOME. |
| Argumentos de linha de comando | Os argumentos passados ao EXE entram depois dos do próprio aplicativo. |
| Modo console | Herda a entrada e a saída padrão do console atual, espera o aplicativo terminar e devolve o código de saída dele. |
| Modo gráfico | Não cria janela de console, o que serve a aplicativos de desktop. |
| Variáveis de ambiente | Limpa antes de iniciar JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS e CLASSPATH, para que nada de fora do pacote injete opções. |
As opções da JVM do EXE ficam fixadas no empacotamento, são assinadas junto com o bloco de parâmetros e verificadas em tempo de execução; depois da implantação não há como alterá-las. APP_JAVA_OPTS só afeta o run.bat — o EXE não o lê. Para mudar as opções da JVM do EXE, empacote de novo.
Pela mesma razão, -javaagent, -agentlib, -agentpath, -Xbootclasspath e --patch-module não podem entrar nas opções de inicialização do EXE. Passá-los por --jvm-option faz o empacotamento falhar na hora.
7. Assinatura de código
O Protector4J não assina o EXE gerado nem acessa credenciais de Authenticode. Todas as alterações do PE — ícone, recursos de versão e opções de inicialização — acontecem durante o empacotamento, de modo que a assinatura tem de vir por último.
- Conclua o empacotamento e confirme que o EXE inicia o aplicativo corretamente.
- Aplique uma assinatura Authenticode com o seu próprio certificado, incluindo carimbo de tempo RFC3161.
- Verifique a assinatura pela diretiva
/pado Windows.
Não altere o arquivo PE depois de assinado: qualquer mudança invalida a assinatura. Para trocar o ícone ou o número de versão, empacote e assine de novo.
8. Campos do arquivo de tarefa
O p4j-task.yml exportado usa a versão 2 do formato e guarda estes campos quando o EXE está ativado. Os arquivos de tarefa na versão 1 continuam podendo ser lidos.
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. Solução de problemas
| Sintoma | Causa e solução |
|---|---|
| Avisa que é preciso uma plataforma-alvo Windows | O EXE está ativado, mas não se marcou windows-x64, windows-x86 nem windows-aarch64. |
| Avisa que o formato da versão é inválido | Um campo de versão traz letras ou espaços, tem mais de quatro partes, ou alguma delas está fora de 0–65535. |
| Avisa que o nome do EXE deve ser só um nome de arquivo | O nome contém um separador de caminho. Use um nome sem pastas. |
| Avisa que o arquivo de ícone não foi encontrado | --exe-icon aponta para um .ico inexistente. Confira o caminho. |
| Depois dos dois cliques não aparece janela e o aplicativo se fecha | O aplicativo falha ao iniciar em modo gráfico. Empacote de novo em modo console para ver a saída de erro. |
| Um EXE copiado para outro lugar não funciona | O iniciador exige o tempo de execução e o arquivo na mesma pasta do pacote. Copie a pasta de saída inteira. |
A lista completa de opções está na Referência da linha de comando; o assistente gráfico é descrito no Guia da interface gráfica.