Uma aplicação Java não termina no código — termina no momento em que o cliente a consegue instalar e executar sem assistência. Este artigo cobre a cadeia completa: o modelo de compilação da JVM, a fronteira de responsabilidades entre developer e cliente, a gestão de dependências externas como o PostgreSQL, e a produção de artefactos de distribuição para Linux e Windows.
Em C, o compilador produz código máquina nativo — instruções binárias específicas
para uma CPU e sistema operativo. Um binário compilado para x86_64 Linux
não corre em ARM Windows. Para múltiplas plataformas, é preciso compilar
uma vez por alvo.
Java introduz uma camada intermédia: o compilador (javac) produz
bytecode — instruções agnósticas à arquitetura, executadas pela JVM
que as traduz para a CPU local em tempo de execução.
gcc app.c -o app → binário x86_64.
Para ARM: recompilar. Para Windows: recompilar.
Vantagem: performance máxima, sem runtime.
Desvantagem: um build por plataforma-alvo.
javac App.java → .class (bytecode).
Um único JAR corre em qualquer plataforma com JVM.
Vantagem: "compile once, run anywhere".
Desvantagem: a JVM tem de estar instalada no destino.
// Cadeia de compilação Java
// 1. Código fonte (.java) → bytecode (.class)
javac src/Main.java
// → target/Main.class (instruções para a JVM, não para a CPU)
// 2. Empacotamento — todos os .class + dependências → fat JAR
mvn package
// → target/autoflow-1.0.0.jar
// 3. Execução — a JVM JIT-compila o bytecode para a CPU local
java -jar autoflow-1.0.0.jar
// → funciona em x86_64 Linux, ARM macOS, x86_64 Windows
// → desde que exista uma JVM compatível instalada
mvn package
com Spring Boot) empacota tudo num único ficheiro autocontido. É o artefacto
de distribuição standard para aplicações Spring Boot.
Quando uma aplicação depende de software externo — como o PostgreSQL — a questão fundamental é: quem instala o quê? Esta divisão deve ser acordada antes do projeto começar, nunca na entrega.
| Responsabilidade | Developer | Cliente / Sysadmin | Notas |
|---|---|---|---|
| Produzir o JAR | ✅ | — | Artefacto final de distribuição. |
| Documentar pré-requisitos | ✅ | — | Versão de Java, PostgreSQL, SO suportados. |
Produzir scripts de BD (.sql) | ✅ | — | Schema, dados iniciais, índices — versionado no repositório. |
Produzir scripts de instalação (.sh / .bat) | ✅ | — | Automatizar o que for possível. Documentar o que não for. |
| Instalar o Java no servidor | — | ✅ | Ou negociado contratualmente. |
| Instalar o PostgreSQL | — | ✅ | Documentar versão mínima e configuração esperada. |
| Executar os scripts de BD | — | ✅ (com suporte) | O developer fornece os scripts; o cliente executa. |
Configurar o application.properties | Fornece template | Preenche | Passwords e hosts são do ambiente do cliente. |
AutoFlow/
├── AutoFlow.jar ← artefacto principal (fat JAR)
├── README.txt ← manual em texto simples (legível sem browser)
├── README.md ← versão Markdown para documentação web
├── config/
│ └── application.properties ← template de configuração (sem passwords reais)
└── setup/
├── schema.sql ← script de criação da BD (idempotente)
├── setup-bd.sh ← instalação para Linux
└── setup-bd.bat ← instalação para Windows
O script SQL de schema é o artefacto mais crítico da distribuição. Deve ser
idempotente (CREATE TABLE IF NOT EXISTS) e versionado no repositório
junto ao código.
-- setup/schema.sql — idempotente e auto-documentado
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(60) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'USER',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Admin por omissão — password deve ser alterada no primeiro login
INSERT INTO users (email, password_hash, role)
VALUES ('admin@autoflow.local', '$2a$12$...', 'ADMIN')
ON CONFLICT (email) DO NOTHING;
#!/bin/bash
# setup/setup-bd.sh — Linux/macOS
set -e
DB_USER="postgres"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "=== AutoFlow — Configuração da Base de Dados ==="
psql -U "$DB_USER" -f "$SCRIPT_DIR/schema.sql"
echo "✓ Base de dados criada. Configura config/application.properties antes de iniciar."
@echo off
REM setup/setup-bd.bat — Windows
set DB_USER=postgres
set SCRIPT_DIR=%~dp0
echo === AutoFlow — Configuração da Base de Dados ===
psql -U %DB_USER% -f "%SCRIPT_DIR%schema.sql"
if %errorlevel% neq 0 (
echo ERRO: Falha. Verifica se o PostgreSQL está instalado e a correr.
pause & exit /b 1
)
echo OK Base de dados criada. Configura config\application.properties antes de iniciar.
pause
O application.properties distribuído deve ser um template
com placeholders documentados — nunca com credenciais reais. As credenciais de produção
pertencem ao ambiente do cliente, não ao repositório.
# config/application.properties — TEMPLATE
spring.datasource.url=jdbc:postgresql://localhost:5432/autoflow
spring.datasource.username=postgres
spring.datasource.password=ALTERAR_AQUI ← obrigatório
server.port=8080
# Gerar com: openssl rand -base64 64
jwt.secret=GERAR_E_COLOCAR_AQUI ← obrigatório
jwt.expiration-minutes=15
spring.profiles.active=prod
application.properties com passwords nunca deve entrar no repositório Git.
Adicionar ao .gitignore. Em produção, usar variáveis de ambiente ou um
secrets manager (HashiCorp Vault, AWS Secrets Manager).
Para clientes menos técnicos, o instalador nativo elimina os pré-requisitos manuais. Em vez de "instala o Java, executa este JAR", o utilizador recebe um instalador que trata de tudo.
.debUm pacote .deb permite instalar com dpkg -i autoflow.deb,
declarar dependências (java17, postgresql), criar serviços
systemd, e desinstalar limpo com apt remove.
# Estrutura do pacote .deb
autoflow_1.0.0_amd64/
├── DEBIAN/
│ ├── control ← metadados: nome, versão, dependências
│ ├── postinst ← script executado após instalação
│ └── prerm ← script executado antes de desinstalar
└── opt/
└── autoflow/
├── autoflow.jar
└── config/
└── application.properties
# DEBIAN/control
Package: autoflow
Version: 1.0.0
Architecture: amd64
Maintainer: RandomT <dev@randomt.pt>
Depends: default-jre-headless (>= 17), postgresql (>= 13)
Description: AutoFlow — Sistema de Gestão
# Construir o pacote
dpkg-deb --build autoflow_1.0.0_amd64
# → autoflow_1.0.0_amd64.deb
# Instalar no cliente — as dependências são verificadas automaticamente
sudo dpkg -i autoflow_1.0.0_amd64.deb
#!/bin/bash
# DEBIAN/postinst — executado automaticamente após instalação
set -e
# Utilizador de sistema dedicado (sem shell de login)
if ! id -u autoflow >/dev/null 2>&1; then
useradd --system --no-create-home --shell /usr/sbin/nologin autoflow
fi
chown -R autoflow:autoflow /opt/autoflow
systemctl enable autoflow
systemctl start autoflow
echo "AutoFlow instalado. Aceder em: http://localhost:8080"
# /etc/systemd/system/autoflow.service
[Unit]
Description=AutoFlow
After=network.target postgresql.service
Requires=postgresql.service
[Service]
User=autoflow
WorkingDirectory=/opt/autoflow
ExecStart=java -jar /opt/autoflow/autoflow.jar
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
O Inno Setup produz um .exe de instalação a partir
de um script .iss que define ficheiros, atalhos, serviços e verificação
de pré-requisitos.
; autoflow.iss — Inno Setup Script
[Setup]
AppName=AutoFlow
AppVersion=1.0.0
DefaultDirName={pf}\AutoFlow
OutputBaseFilename=AutoFlow-Setup-1.0.0
[Files]
Source: "dist\autoflow.jar"; DestDir: "{app}"; Flags: ignoreversion
Source: "dist\config\*"; DestDir: "{app}\config"; Flags: recursesubdirs
Source: "dist\setup\*"; DestDir: "{app}\setup"; Flags: recursesubdirs
[Run]
; Executar o script de BD após instalação
Filename: "{app}\setup\setup-bd.bat";
Description: "Criar base de dados PostgreSQL";
Flags: postinstall runascurrentuser
[Code]
// Verificar Java antes de instalar
function InitializeSetup(): Boolean;
begin
Result := True;
if Exec('java', '-version', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
Result := True
else begin
MsgBox('Java 17 não encontrado. Instala o Java antes de continuar.', mbError, MB_OK);
Result := False;
end;
end;
| Ficheiro | Formato | Audiência | Onde usar |
|---|---|---|---|
README.txt | Texto simples ASCII | Sysadmin, terminal, cliente técnico | Dentro do ZIP de distribuição. Legível sem browser. |
README.md | Markdown | Developer, documentação web | Repositório Git, GitBook, Notion, Academy. |
| Página HTML | HTML estruturado | Equipa interna, parceiros | Este site — manual completo com exemplos de código. |
mvn package com Spring Boot Plugin — todas as dependências dentro.CREATE TABLE IF NOT EXISTS — re-executável sem destruir dados..sh e .bat se a aplicação for multiplataforma.application.properties com placeholders, sem credenciais reais.Ctrl+C e pkill — frequentemente esquecida.psql — para o cliente administrar sem o developer.