☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

terça-feira, 3 de janeiro de 2023

🕵️‍♂️ Tintin na Terra dos Containers — O Mistério de Docker & Kubernetes

 

Bellacosa Mainframe e os containers dockers e kubernetes

☕ Um Café no Bellacosa Mainframe

🕵️‍♂️ Tintin na Terra dos Containers — O Mistério de Docker & Kubernetes

Uma investigação entre imagens, containers, Pods, Deployments e clusters — porque até Tintin descobriria que colocar uma aplicação em produção é muito mais complicado do que embarcar no Sirius.

Caso nº 03:17 — Arquivo confidencial do Bellacosa Mainframe
Destino: Produção
Suspeitos: Docker, Kubernetes e algumas dezenas de arquivos YAML
Situação: aparentemente simples. Portanto, extremamente suspeita.

Tintin estava acostumado a situações complicadas.

Já havia enfrentado falsificadores, contrabandistas, sociedades secretas, ditadores, traficantes, cientistas excêntricos e até viajado à Lua.

Mas naquela manhã encontrou algo muito mais perigoso.

Um desenvolvedor havia pronunciado a frase:

— Na minha máquina funciona.

Milou levantou as orelhas.

Capitão Haddock largou o café.

Professor Girassol continuou mexendo em alguma coisa que provavelmente explodiria antes do almoço.

Tintin abriu seu pequeno caderno.

Novo caso.

Precisávamos descobrir como levar uma aplicação desde o notebook de um programador até produção sem depender da configuração particular daquela máquina.

E nossa investigação começaria com uma criatura chamada container.



📰 1. O estranho caso da aplicação que funcionava ontem

Imagine que nosso jovem programador COBOL decidiu aprender Python e criou uma pequena API usando FastAPI.

No computador dele tudo funciona.

Python instalado.

Bibliotecas instaladas.

Variáveis configuradas.

Banco de dados acessível.

Portas abertas.

Versões corretas.

Ele entrega o programa para Haddock.

Haddock tenta executá-lo.

Nada funciona.

MIL MILHÕES DE MILHARES DE BIBLIOTECAS INCOMPATÍVEIS!

Eis um problema muito antigo da computação.

O programa não existe sozinho.

Ele depende de um ambiente.

No universo mainframe conhecemos isso muito bem. Um programa COBOL pode depender de determinada versão de runtime, Db2, CICS, arquivos, configurações, parâmetros, bibliotecas e permissões.

No mundo distribuído ocorre exatamente o mesmo fenômeno.

Docker ataca justamente esse problema.

Em vez de entregar apenas:

minha-aplicacao.py

tentamos empacotar:

APLICAÇÃO
   +
RUNTIME
   +
BIBLIOTECAS
   +
DEPENDÊNCIAS
   +
CONFIGURAÇÃO NECESSÁRIA

dentro de uma unidade reproduzível.

Tintin anotaria:

Pista nº 1: não transporte apenas o programa. Transporte uma descrição reproduzível de seu ambiente.



📦 2. Surge a primeira testemunha: Docker

Docker popularizou uma maneira extremamente prática de construir, distribuir e executar aplicações em containers.

Mas precisamos separar duas palavras que frequentemente aparecem misturadas:

IMAGE e CONTAINER.

Uma imagem é o artefato preparado.

Um container é uma instância executando aquela imagem.

Podemos imaginar:

Dockerfile
    │
    ▼
docker build
    │
    ▼
┌─────────────────┐
│      IMAGE      │
│ app:v1          │
└─────────────────┘
       │
       │ docker run
       ▼
┌─────────────────┐
│    CONTAINER    │
│ aplicação viva  │
└─────────────────┘

Para quem vem do mainframe, existe uma analogia didática interessante.

Imagem lembra um artefato executável versionado. Container lembra uma execução desse artefato.

Não interprete isso literalmente como LOAD MODULE = IMAGE, porque arquiteturalmente são coisas diferentes.

Mas como ponte mental funciona muito bem.

O detalhe importante é:

uma única imagem pode originar muitos containers.

Temos:

IMAGE: bellacard-api:v7

        │
        ├── Container A
        ├── Container B
        ├── Container C
        └── Container D

Agora Tintin já tinha uma pista importante.

O artefato poderia ser reproduzido.


🧾 3. O bilhete encontrado no bolso do suspeito: Dockerfile

Toda boa investigação tem um documento comprometedor.

No nosso caso:

FROM python:3.13-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["python", "app.py"]

Esse arquivo é o Dockerfile.

Ele descreve como construir nossa imagem.

Tintin examina cada linha com a lupa.

FROM determina a imagem-base.

WORKDIR estabelece o diretório de trabalho.

COPY coloca arquivos dentro da imagem.

RUN executa comandos durante sua construção.

ENV pode definir variáveis de ambiente.

CMD estabelece o comando normalmente executado quando o container começa.

E então aparece:

EXPOSE 8000

Haddock imediatamente conclui:

— Então a porta 8000 está publicada!

Não.

EXPOSE não publica automaticamente uma porta no host.

É informação sobre a porta esperada pela aplicação. A publicação efetiva pode ser feita, por exemplo:

docker run -p 8080:8000 bellacard-api

Temos então:

HOST                  CONTAINER

localhost:8080  ───►  :8000

Essa diferença pequena é exatamente o tipo de detalhe que transforma uma explicação introdutória em conhecimento operacional.



🌐 4. O mistério das portas

Tintin agora encontra três containers.

frontend
backend
database

Cada um possui seu próprio contexto de rede.

E aqui surge outra mudança mental importante.

Não devemos construir sistemas distribuídos supondo que cada container terá eternamente determinado endereço IP.

Containers aparecem.

Containers desaparecem.

Podem ser recriados.

É muito melhor trabalhar com nomes e mecanismos de descoberta de serviços.

Em um ambiente Docker Compose poderíamos ter:

frontend
    │
    ▼
backend:8000
    │
    ▼
postgres:5432

Isso começa a revelar algo importante.

Containerização não significa simplesmente:

“pegamos uma VM e diminuímos.”

O modelo operacional é diferente.

Containers tendem a ser descartáveis.

A aplicação precisa ser projetada levando isso em consideração.



💾 5. Milou encontra o banco de dados

Milou começa a latir para um container.

Tintin abre o container.

Encontra PostgreSQL.

Haddock reinicia a máquina.

O banco desaparece.

BOMBARDEIOS E BACKUPS INEXISTENTES!

Tintin identifica imediatamente o problema.

Persistência.

O filesystem interno de um container não deve ser tratado ingenuamente como o lugar permanente dos dados importantes.

Precisamos separar:

COMPUTE                  DATA

container              volume/storage
 descartável            persistente

Docker oferece mecanismos como volumes e bind mounts.

Essa separação torna-se ainda mais importante quando chegarmos ao Kubernetes.

Uma aplicação pode morrer.

O Pod pode desaparecer.

O container pode ser substituído.

Mas determinados dados precisam continuar existindo.

Para quem vem de mainframe isso não deveria parecer revolucionário.

Há décadas aprendemos a separar processamento de dados persistentes.

A novidade está nas abstrações utilizadas.



🗝️ 6. O envelope secreto

Girassol encontra isto:

DB_PASSWORD=Tintin123
API_KEY=abc123

E sugere colocar tudo no GitHub.

Tintin quase derruba o café.

Variáveis de ambiente são excelentes para retirar determinadas configurações do código.

Podemos ter:

APP_ENV=production
DB_HOST=database
DB_PORT=5432

Arquivos .env também são muito convenientes durante desenvolvimento.

Mas existe uma armadilha:

tirar uma senha do código não significa que ela automaticamente ficou segura.

Um .env contendo credenciais continua sendo um arquivo contendo credenciais.

Precisa ser protegido.

Não deve simplesmente parar no repositório.

E esse problema reaparecerá no Kubernetes com os Secrets.


🧩 7. O caso ficou grande demais: Docker Compose

Tintin agora possui cinco containers:

frontend
API
agent
database
redis

Executá-los manualmente começa a parecer uma operação militar.

Então entra Docker Compose.

Podemos declarar um conjunto de serviços em um arquivo compose.yaml.

Algo conceitualmente semelhante a:

services:

  api:
    build: .
    ports:
      - "8000:8000"

  database:
    image: postgres

  redis:
    image: redis

Agora descrevemos uma pequena aplicação multi-container declarativamente.

Essa é uma das grandes virtudes do Compose.

Em vez de Haddock precisar decorar quinze comandos, declaramos como o ambiente deve ser.

Um detalhe merece atualização nos materiais mais antigos: no Compose moderno, aquele tradicional:

version: "3.8"

não é mais necessário. A documentação do Docker classifica a propriedade superior version como obsoleta e meramente informativa; o Compose moderno trabalha com a Compose Specification. (Docker Documentation)

É um belo exemplo de por que bons cursos técnicos precisam ser revisados continuamente.


🚢 8. Finalmente embarcamos a imagem

Construímos nossa aplicação:

docker build -t bellacard:v1 .

Temos uma imagem local.

Mas queremos executá-la em outro lugar.

Entram os container registries.

O fluxo conceitual torna-se:

SOURCE CODE
     │
     ▼
DOCKERFILE
     │
     ▼
BUILD
     │
     ▼
IMAGE
     │
     ▼
REGISTRY
     │
     ▼
PULL
     │
     ▼
EXECUTION

É aqui que começa uma ideia extremamente poderosa:

o artefato produzido pelo pipeline deve ser exatamente aquilo que promovemos entre ambientes.

Não queremos recompilar misteriosamente produção de maneira diferente de homologação.

Queremos artefatos versionados, rastreáveis e reproduzíveis.

O velho programador mainframe sentado no fundo da sala provavelmente começa a sorrir.

Ele já ouviu essa música antes.


🌊 9. De repente aparecem 500 containers

E aqui nossa aventura muda completamente.

Docker resolveu muito bem vários problemas relacionados a construção e execução de containers.

Mas suponha que nossa aplicação tenha:

300 containers
40 servidores
12 serviços
6 versões
3 ambientes
milhares de requisições

Quem decide onde cada workload executará?

Quem percebe que um deles morreu?

Quem cria outro?

Quem mantém determinada quantidade de réplicas?

Quem distribui tráfego?

Quem atualiza gradualmente uma versão?

Quem associa armazenamento?

Quem controla configuração?

Quem escala a aplicação?

Tintin escreve uma única palavra no caderno:

KUBERNETES


☸️ 10. Entramos no território Kubernetes

Kubernetes não é simplesmente um “Docker maior”.

Essa distinção é fundamental.

Ele é uma plataforma de orquestração de workloads containerizados.

Seu grande truque filosófico está no conceito de estado desejado.

Nós declaramos algo como:

QUERO 3 RÉPLICAS DESTA APLICAÇÃO.

O sistema observa:

DESEJADO = 3
ATUAL = 3

Tudo certo.

Um Pod desaparece:

DESEJADO = 3
ATUAL = 2

Existe divergência.

Os controladores trabalham para retornar ao estado desejado:

DESEJADO = 3
ATUAL = 3

Isso é extraordinariamente importante.

O operador deixa de pensar apenas:

“execute este comando.”

e passa também a pensar:

“este é o estado que quero manter.”

Quem conhece automação operacional, WLM e políticas em ambientes corporativos provavelmente já começou a enxergar pontes conceituais.


🏰 11. Tintin entra no cluster

Um cluster Kubernetes possui componentes de controle e nós onde workloads são executados.

De forma simplificada:

              KUBERNETES CLUSTER

        ┌─────────────────────────┐
        │      CONTROL PLANE      │
        │                         │
        │ API Server              │
        │ Scheduler               │
        │ Controller Manager      │
        │ etcd                    │
        └────────────┬────────────┘
                     │
          ───────────┼───────────
                     │
       ┌─────────────┴─────────────┐

   WORKER NODE                 WORKER NODE
   ┌──────────────┐           ┌──────────────┐
   │ kubelet      │           │ kubelet      │
   │ runtime      │           │ runtime      │
   │              │           │              │
   │ Pod Pod Pod  │           │ Pod Pod Pod  │
   └──────────────┘           └──────────────┘

O API Server é uma peça central da interface de controle.

O scheduler ajuda a decidir onde Pods serão colocados.

Os controllers observam o estado e trabalham para reconciliá-lo.

O etcd mantém dados importantes do estado do cluster.

E nos workers temos, entre outros componentes, o kubelet e um runtime de containers.


🐳 12. Haddock encontra uma pista desatualizada

Em algum velho mapa Tintin encontra:

Kubernetes → Docker

— Caso encerrado! — grita Haddock.

Não tão depressa.

Aqui existe uma atualização histórica importantíssima.

Kubernetes removeu seu dockershim integrado a partir da versão 1.24. Kubernetes moderno trabalha através da Container Runtime Interface — CRI, com runtimes compatíveis, como containerd e CRI-O; Docker Engine ainda pode ser integrado por um adaptador como cri-dockerd. (Kubernetes)

Isso não significa que imagens construídas com Docker deixaram de funcionar no Kubernetes. A própria documentação explica que usar Docker para construir imagens não cria uma dependência de Docker como runtime do cluster. (Kubernetes)

Portanto nosso mapa mental moderno é melhor representado assim:

              KUBERNETES

                 kubelet
                    │
                    ▼
                   CRI
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
     containerd             CRI-O

E Docker continua extremamente útil no workflow de desenvolvimento e construção de imagens.

Pista nº 12: Docker não morreu no Kubernetes. Mudou a relação arquitetural entre eles.


📦 13. O menor quarto do hotel: Pod

Chegamos agora a uma das palavras mais importantes de Kubernetes:

Pod.

Pod é a menor unidade implantável de computação que Kubernetes gerencia.

Normalmente encontramos um container principal dentro dele, embora um Pod possa conter mais de um container quando esses processos precisam compartilhar estreitamente recursos e ciclo de vida.

Podemos imaginar:

POD
┌────────────────────────────┐
│                            │
│   Application Container    │
│                            │
│   shared networking        │
│   shared volumes/context   │
│                            │
└────────────────────────────┘

Mas existe algo fundamental:

não se apaixone pelo Pod.

Pods são substituíveis.

Podem desaparecer e serem recriados.

E por isso normalmente não administramos aplicações complexas criando Pods soltos manualmente.

Entra outra testemunha.


🧬 14. Deployment → ReplicaSet → Pods

Para uma aplicação típica, podemos declarar um Deployment.

Por exemplo:

replicas: 3

Conceitualmente:

Deployment
     │
     ▼
ReplicaSet
     │
 ┌───┼───┐
 ▼   ▼   ▼
Pod Pod Pod

Se um desaparece:

Pod ✖

o sistema trabalha para restaurar o estado desejado.

Isso também permite realizar rolling updates.

Em vez de:

VERSÃO 1
   ↓
DESLIGA TUDO
   ↓
VERSÃO 2

podemos substituir progressivamente instâncias antigas por novas.

E, quando necessário, trabalhar com mecanismos de rollback.

Haddock começa a gostar da história.

Produção sem uma gigantesca janela de “desliga tudo e reza” realmente parece civilização.


📞 15. Mas como encontramos esses Pods?

Temos outro problema.

Pods são efêmeros.

Se ficarmos distribuindo seus endereços diretamente, criamos dependências frágeis.

Entra o objeto Service.

Imagine:

CLIENTE
   │
   ▼
SERVICE
   │
 ┌─┼───────────┐
 ▼ ▼           ▼
POD A        POD B        POD C

O Service fornece uma abstração estável para alcançar determinado conjunto de Pods.

Essa é uma mudança mental importantíssima:

não procure indivíduos; procure o serviço.

Para um programador mainframe acostumado com um endpoint lógico de uma aplicação transacional, a ideia começa a soar curiosamente familiar.


🗺️ 16. ConfigMap e o documento que não deveria conter a senha

Nossa aplicação precisa saber:

LOG_LEVEL=INFO
LANGUAGE=pt_BR
FEATURE_X=true

Esses valores podem estar em um ConfigMap.

Mas temos também:

PASSWORD
TOKEN
API_KEY
CERTIFICATE

Aí entramos no território dos Secrets.

Contudo, há uma pegadinha digna dos irmãos Dupond e Dupont:

— Está em Base64, portanto está criptografado!

— Exatamente! E eu diria ainda mais: está criptografado porque está em Base64!

Errado duas vezes.

A documentação oficial é explícita: Base64 não é criptografia. Kubernetes Secrets podem ser armazenados sem criptografia por padrão; ambientes sérios precisam considerar controles como RBAC, restrição de acesso, criptografia em repouso e soluções apropriadas de gerenciamento de segredos. (Kubernetes)

Portanto:

ConfigMap
    ↓
configuração não confidencial

Secret
    ↓
informação confidencial
    ↓
+ controle de acesso
+ proteção apropriada
+ encryption at rest quando aplicável
+ gestão segura do ciclo de vida

Esse é um ponto que merece enorme atenção em qualquer treinamento.


🗄️ 17. O banco não pode desaparecer novamente

Voltamos ao problema de persistência.

No Kubernetes encontramos conceitos como:

PersistentVolume — PV

e

PersistentVolumeClaim — PVC

Didaticamente:

POD
 │
 ▼
PVC
 │
 ▼
PV
 │
 ▼
STORAGE

O PVC representa a solicitação de armazenamento feita pelo workload.

O PV representa o recurso persistente disponibilizado ao cluster, dependendo do modelo e provisionamento utilizado.

Em ambientes modernos existe ainda toda uma camada envolvendo StorageClass, provisionamento dinâmico e CSI.

Mas para nossa primeira investigação basta guardar:

Pod é descartável; dado importante não pode depender da sobrevivência daquele Pod.


🩺 18. Professor Girassol inventa três estetoscópios

Agora precisamos saber se a aplicação está saudável.

Kubernetes trabalha com probes que respondem perguntas diferentes.

Startup probe:

Você conseguiu iniciar?

Liveness probe:

Você continua vivo?

Readiness probe:

Você está pronto para receber tráfego?

Essas perguntas parecem semelhantes.

Não são.

Imagine uma aplicação Java que demora bastante para iniciar.

Ela pode estar viva, mas ainda não pronta para atender.

Ou uma aplicação pode continuar com processo existente, mas ter entrado em um estado do qual não consegue se recuperar adequadamente.

Misturar esses conceitos pode produzir exatamente o tipo de incidente que começa às...

03:17.

Pronto.

Easter egg encontrado. ☕😎


🚪 19. Tintin chega ao portão: Ingress

Agora temos serviços funcionando dentro do cluster.

Mas usuários precisam chegar até eles.

Tradicionalmente, Kubernetes utiliza Ingress para definir roteamento HTTP/HTTPS externo, associado a uma implementação/controlador.

Conceitualmente:

INTERNET
   │
   ▼
INGRESS
   │
   ├── /api ─────► Service API
   │                    │
   │                  Pods
   │
   └── /web ─────► Service WEB
                        │
                      Pods

Ingress continua sendo um conceito importante porque existem enormes ambientes usando-o.

Porém nosso curso de 2026 precisa colocar uma anotação vermelha no caderno de Tintin:

⚠️ EXISTE UM NOVO CAPÍTULO

O ecossistema Kubernetes está avançando para Gateway API como abordagem moderna e mais expressiva para networking. Em agosto de 2026, o projeto anunciou Gateway API v1.6, incluindo TCPRoute e UDPRoute no canal Standard. (Kubernetes)

Há inclusive tooling oficial para ajudar migrações de Ingress para Gateway API. (Kubernetes)

Portanto um curso atualizado deveria ensinar:

Ingress
   │
   ├── importantíssimo para ambientes existentes
   │
   └── API congelada para novos recursos
             │
             ▼
         Gateway API
        caminho moderno

Esse pequeno detalhe separa uma apostila histórica de uma formação preparada para os próximos anos.


📈 20. De repente chegam dez mil usuários

Haddock finalmente publica seu sistema.

Um usuário acessa.

Tudo funciona.

Dez acessam.

Tudo funciona.

Mil acessam.

Haddock começa a suar.

Dez mil acessam.

ESCALABILIDADE DOS SETE MARES!

Kubernetes oferece mecanismos de escalabilidade, entre eles o Horizontal Pod Autoscaler — HPA.

Podemos pensar:

TRÁFEGO ↑
CPU ↑
MÉTRICA ↑

       │
       ▼

HPA observa
       │
       ▼

replicas: 3
       │
       ▼
replicas: 7

Quando a demanda diminui, a quantidade pode ser reduzida segundo a configuração e comportamento do autoscaler.

CPU e memória são excelentes exemplos introdutórios, embora arquiteturas reais possam utilizar outras métricas conforme a infraestrutura de métricas disponível.

Aqui encontramos uma ponte interessante com o universo mainframe.

Um profissional de WLM imediatamente perguntaria:

Qual é a política? Qual a prioridade? Qual o recurso disponível? Qual a métrica? Qual o objetivo de serviço?

Excelente.

Essa é exatamente a mentalidade que queremos preservar.

A tecnologia muda.

As boas perguntas sobrevivem.


🧠 21. Tintin monta o quadro completo

Depois de centenas de pistas espalhadas pela mesa, finalmente conseguimos enxergar nossa arquitetura.

                    INTERNET
                        │
                        ▼
              ┌──────────────────┐
              │ GATEWAY/INGRESS  │
              └────────┬─────────┘
                       │
                       ▼
                  ┌─────────┐
                  │ SERVICE │
                  └────┬────┘
                       │
              ┌────────┼────────┐
              ▼        ▼        ▼
             POD      POD      POD
              ▲        ▲        ▲
              └────────┼────────┘
                       │
                  ReplicaSet
                       ▲
                       │
                  Deployment
                       │
             desired replicas = 3


       CONFIGURAÇÃO                DADOS

        ConfigMap                   PVC
        Secrets                      │
                                     ▼
                                     PV
                                     │
                                     ▼
                                  STORAGE

E por trás disso existe o cluster:

CONTROL PLANE
      │
      ├── API Server
      ├── Scheduler
      ├── Controllers
      └── etcd
             │
             ▼
        WORKER NODES
             │
             ▼
           kubelet
             │
             ▼
             CRI
             │
       container runtime
             │
             ▼
            Pods

Finalmente o mistério começa a fazer sentido.


🏦 22. E onde entra o mainframe nessa aventura?

Aqui está talvez a parte mais interessante para quem está entrando nesse mundo vindo de COBOL, CICS, Db2 e z/OS.

Você não precisa apagar quarenta anos de conhecimento para aprender containers.

Muito pelo contrário.

Quem passou anos pensando em disponibilidade, processamento transacional, controle de acesso, recuperação, armazenamento, capacidade, versionamento e produção já possui uma enorme bagagem conceitual.

O segredo é não procurar equivalências literais.

Não diga:

CICS = Kubernetes
JES2 = Kubernetes
WLM = HPA
RACF = RBAC

Não são.

Mas use essas tecnologias como pontes cognitivas.

Você conhece a pergunta:

Quem pode executar isto?

Ótimo. Vamos conversar sobre RBAC.

Você conhece:

Onde os dados sobrevivem?

Excelente. Vamos falar de persistent storage.

Você pergunta:

O que acontece se esta execução morrer?

Bem-vindo ao desired state e reconciliation.

Você pergunta:

Como distribuir capacidade?

Vamos estudar scheduler, requests, limits e autoscaling.

Você pergunta:

Como colocar uma nova versão sem explodir produção?

Deployment, rolling updates, probes, observabilidade e estratégias de rollout estão esperando por você.

O veterano não chega vazio a Kubernetes.

Chega carregando décadas de perguntas extremamente úteis.


🚂 23. A viagem completa

Agora podemos reconstruir toda nossa investigação em uma única linha narrativa.

Tintin recebe:

SOURCE CODE

Cria:

Dockerfile

Produz:

IMAGE

Publica:

REGISTRY

Kubernetes referencia essa imagem.

Um:

Deployment

define o workload desejado.

Ele administra ReplicaSets que mantêm:

Pods

Esses Pods são alcançados por:

Service

Configuração chega através de mecanismos como:

ConfigMap
Secret

Dados persistentes podem utilizar:

PVC → PV → Storage

Saúde pode ser acompanhada com:

startup
readiness
liveness

Tráfego externo pode chegar através de:

Gateway API / Ingress

E escalabilidade horizontal pode envolver:

HPA

Isso já não parece uma coleção aleatória de palavras.

Parece uma arquitetura.


🔎 24. O que as excelentes ilustrações escondem

Os infográficos que iniciaram nossa investigação são ótimos para aquilo que considero a primeira passagem pelo território.

Você olha.

Reconhece os nomes.

Entende as relações.

Executa alguns comandos.

Constrói uma imagem.

Executa containers.

Cria um Compose.

Publica uma imagem.

Cria Pod.

Deployment.

Service.

PVC.

Ingress.

HPA.

Excelente.

Mas existe uma segunda passagem.

É nela que começamos a perguntar:

“Como isso funciona em produção?”

Então surgem novos personagens:

Namespaces
RBAC
ServiceAccounts
NetworkPolicy
requests/limits
taints
tolerations
affinity
anti-affinity
PodDisruptionBudget
StorageClass
CSI
Helm
Kustomize
observability
metrics
logging
tracing
GitOps
CI/CD
supply-chain security
image scanning
policy enforcement
Gateway API

E existe uma terceira passagem ainda mais interessante para nós:

Kubernetes + IBM Z + LinuxONE + OpenShift + z/OS

Aí a história deixa de ser simplesmente:

“mainframe versus cloud.”

Passa a ser:

“qual workload deve executar onde?”

Esse é um problema arquitetural muito mais adulto.


🚀 25. Bellacosa Containers 101 → 201 → 301

Eu transformaria todo esse material em uma trilha em três atos.

101 — Tintin descobre os containers: Linux essencial, Docker, imagens, containers, Dockerfile, registry, networking, volumes, environment variables, secrets e Compose.

201 — Tintin encontra Kubernetes: cluster, control plane, worker, kubectl, Pod, Deployment, ReplicaSet, Service, ConfigMap, Secret, PV/PVC, probes, requests/limits, Ingress, Gateway API e HPA.

301 — Tintin entra em produção: RBAC, namespaces, NetworkPolicy, CSI, Helm/Kustomize, observabilidade, segurança, CI/CD, GitOps, supply chain, OpenShift, LinuxONE/IBM Z e integração de workloads containerizados com serviços corporativos e z/OS.

O aluno poderia começar com:

docker run hello-world

e terminar compreendendo algo como:

Internet
   │
Gateway
   │
OpenShift/Kubernetes
   │
Containerized API
   │
MQ / REST
   │
z/OS Connect
   │
CICS
   │
COBOL
   │
Db2

Agora estamos falando a língua do Bellacosa Mainframe.


🏁 Epílogo — Tintin fecha o caderno

Depois de horas investigando containers, imagens, registries, Pods, Deployments, Services, Secrets e clusters, Capitão Haddock finalmente perguntou:

— Então Kubernetes substitui o mainframe?

Tintin fechou o caderno.

Milou olhou para Haddock.

Professor Girassol fingiu não ouvir.

E um velho programador COBOL sentado no canto começou a rir.

Porque essa era a pergunta errada.

Mainframes resolvem determinados problemas extraordinariamente bem.

Containers resolvem outros.

Kubernetes resolve um problema importantíssimo de orquestração e gerenciamento de workloads containerizados em escala.

E arquiteturas modernas podem combinar esses mundos.

A verdadeira habilidade do arquiteto não é escolher uma tecnologia para vencer uma guerra imaginária.

É saber onde cada workload pertence, como conectá-lo aos demais e como operar o conjunto com segurança, disponibilidade e previsibilidade.

Tintin guardou a lupa.

Haddock terminou o café.

Milou finalmente encontrou o container desaparecido.

E o veterano COBOL abriu um terminal e digitou:

kubectl get pods

Havia três.

bellacard-7f84c      Running
bellacard-2b17d      Running
bellacard-91a2e      Running

Deployment desejava três.

Produção tinha três.

Por alguns preciosos minutos, o universo estava em equilíbrio.

Até o telefone tocar.

Eram 03:17.

— Tintin... caiu produção.

Ele pegou o sobretudo.

— Milou, estamos diante de um novo caso.

Bellacosa Mainframe — porque a tecnologia muda, mas produção continua encontrando maneiras criativas de acordar alguém de madrugada.




sábado, 31 de dezembro de 2022

COBOL, QSAM e Db2 sem Mistérios: a Jornada do Arquivo Sequencial até o INSERT na Tabela

 

Bellacosa Mainframe executando cobol com db2 e qsam

☕ Um Café no Bellacosa Mainframe

COBOL, QSAM e Db2 sem Mistérios: a Jornada do Arquivo Sequencial até o INSERT na Tabela

Imagine a cena: madrugada no datacenter, luzes azuis refletindo nos corredores, o IBM Z trabalhando silenciosamente e, diante da tela 3270, um programador COBOL padawan observa um pequeno JCL.

À primeira vista, são poucas linhas:

//EXECDB2 EXEC PGM=IKJEFT01,DYNAMNBR=20
//STEPLIB DD DSN=DSN910.SDSNLOAD,DISP=SHR
//LISTCOPAC DD DSN=INFEF00.COPIA.MUNDO,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//SYSTSIN  DD *
  DSN SYSTEM(DB9G)
  RUN PROGRAM(COBDB501) PLAN(HERP0001) -
      LIB('ADCD.Z112.USERLOAD')
/*

Mas o verdadeiro mainframe nunca entrega todos os seus segredos de imediato.

Por trás dessas linhas existe uma cadeia completa de tecnologias:

JES2
  ↓
JCL
  ↓
IKJEFT01
  ↓
TSO Batch
  ↓
DSN Command Processor
  ↓
Db2 Attachment Facility
  ↓
PLAN
  ↓
PACKAGE
  ↓
Programa COBOL
  ↓
QSAM
  ↓
Arquivo sequencial
  ↓
INSERT no Db2
  ↓
COMMIT ou ROLLBACK

O JCL é pequeno, mas representa o último estágio de uma fábrica inteira de software. Antes de chegar a essa execução, alguém escreveu um programa COBOL, processou SQL pelo precompiler, compilou, linkeditou, gerou um load module, criou um DBRM, executou BIND PACKAGE, criou ou atualizou um PLAN e autorizou o usuário.

Vamos abrir cada porta desse templo tecnológico.


Bellacosa Mainframe executando um programa cobol db2 e qsam

1. Qual é a missão deste programa?

O próprio comentário do JCL entrega a missão:

//* PROGRAMA LE QSAM E INSERE TABELAS DB2

Em linguagem simples, o programa deverá:

  1. abrir um arquivo sequencial;

  2. ler cada registro;

  3. separar os campos;

  4. validar os dados;

  5. executar um INSERT em uma tabela Db2;

  6. tratar registros inválidos;

  7. realizar COMMIT;

  8. fechar o arquivo;

  9. retornar um código ao sistema operacional.

Um fluxo provável seria:

Abrir arquivo LISTCOPAC
        ↓
Ler primeiro registro
        ↓
Registro válido?
   ┌────┴────┐
   │         │
  Sim       Não
   │         │
INSERT      Registrar erro
   │         │
   └────┬────┘
        ↓
Atingiu intervalo de COMMIT?
        ↓
Executar COMMIT
        ↓
Ler próximo registro
        ↓
Fim do arquivo?
   ┌────┴────┐
   │         │
  Não       Sim
   │         │
Repetir     COMMIT final
             ↓
        Fechar arquivo
             ↓
           GOBACK

Esse tipo de programa é muito comum em sistemas corporativos.

Ele pode carregar:

  • clientes;

  • contas;

  • pagamentos;

  • movimentações;

  • produtos;

  • contratos;

  • dados de interfaces;

  • informações recebidas de outros sistemas;

  • arquivos produzidos por plataformas distribuídas.

É uma ponte entre o mundo dos arquivos batch e o mundo relacional do Db2.


2. O papel do JES

Antes que qualquer programa seja executado, o job precisa ser entregue ao JES.

JES significa Job Entry Subsystem.

Em muitos ambientes z/OS utiliza-se o JES2. Ele recebe o JCL, analisa as instruções, prepara os recursos, controla a execução e organiza as saídas no spool.

Quando o programador digita:

SUB

no ISPF Edit, não está executando o COBOL diretamente.

Na realidade, está entregando um pedido ao JES:

“JES, aceite este conjunto de instruções, valide o JCL, encontre os recursos e execute os steps na ordem indicada.”

O JES então:

  1. atribui um JOBID;

  2. lê o JCL;

  3. faz a conversão;

  4. verifica procedimentos;

  5. coloca o job na fila;

  6. seleciona uma initiator;

  7. executa os steps;

  8. recolhe as mensagens;

  9. grava os resultados no spool.

O nome mostrado na tela:

CATPGM1

é o nome do job.

O identificador:

JOB00056

é o JOBID atribuído pelo JES.

Esses dois nomes parecem semelhantes, mas representam coisas diferentes:

CATPGM1  = nome lógico fornecido no cartão JOB
JOB00056 = número atribuído pelo JES

3. A biblioteca JOBLIB

Na imagem existe:

//JOBLIB DD DSN=IBMUSER.CBL.LOADLIB,DISP=SHR

A JOBLIB define uma biblioteca de módulos executáveis para o job inteiro.

É como dizer:

“Ao procurar programas deste job, inclua esta biblioteca na busca.”

A biblioteca:

IBMUSER.CBL.LOADLIB

deve ser uma PDS ou PDSE contendo load modules ou program objects.

Um programa COBOL não é executado diretamente a partir do fonte:

IBMUSER.CBL.SOURCE(COBDB501)

O fonte precisa atravessar um processo:

Fonte COBOL
     ↓
Precompile Db2
     ↓
Compilação COBOL
     ↓
Object module
     ↓
Binder ou Link-edit
     ↓
Load module

O resultado final pode estar armazenado como:

IBMUSER.CBL.LOADLIB(COBDB501)

Um detalhe importante

No step da imagem também existe uma STEPLIB:

//STEPLIB DD DSN=DSN910.SDSNLOAD,DISP=SHR

Quando um step possui STEPLIB, ela normalmente substitui a JOBLIB para a busca de módulos naquele step.

Portanto, a existência de JOBLIB não significa que ela será usada pelo step EXECDB2.

Essa é uma daquelas curiosidades que derrubam muitos padawans.

O programador pensa:

“Meu programa está na JOBLIB, portanto será encontrado.”

Mas o sistema responde:

“Existe uma STEPLIB neste step. Minha busca seguirá outro caminho.”

No caso do JCL apresentado, o programa da aplicação é localizado por meio da cláusula:

LIB('ADCD.Z112.USERLOAD')

Isso evita que ele dependa da JOBLIB.


4. O step EXECDB2

//EXECDB2 EXEC PGM=IKJEFT01,DYNAMNBR=20

Essa linha cria um step chamado:

EXECDB2

O nome do step é escolhido pelo desenvolvedor.

Ele poderia ser:

//STEP01
//RUNCOB
//DB2RUN
//CARREGA

Um bom nome melhora a análise do spool.

Ao observar:

EXECDB2

já sabemos que aquele step provavelmente executará alguma coisa em um ambiente Db2.

A instrução:

EXEC PGM=IKJEFT01

determina o programa que o z/OS carregará inicialmente.

E aqui surge uma pergunta importante:

Por que o JCL não executa diretamente COBDB501?

Porque COBDB501 contém SQL estático e precisa executar conectado ao subsistema Db2. O IKJEFT01 cria o ambiente TSO batch, dentro do qual o command processor DSN estabelece essa conexão.

Assim, a sequência real é:

IKJEFT01
   ↓
Comando DSN
   ↓
DSN SYSTEM(DB9G)
   ↓
RUN PROGRAM(COBDB501)

5. O que é o IKJEFT01?

O IKJEFT01 é um programa do z/OS utilizado para executar comandos TSO em batch.

O TSO é normalmente associado ao trabalho interativo:

READY

O usuário digita comandos e recebe respostas.

Com IKJEFT01, não existe uma pessoa digitando os comandos. Eles são fornecidos por um dataset ou por dados instream no DD SYSTSIN.

Uma analogia Bellacosa:

  • TSO interativo é o Jedi no terminal;

  • IKJEFT01 é o droide que repete os comandos durante a madrugada;

  • SYSTSIN é o pergaminho com as ordens;

  • SYSTSPRT é o diário da missão.

O IKJEFT01 pode executar:

  • comandos TSO;

  • CLISTs;

  • execuções REXX;

  • comandos do Db2;

  • utilitários que dependem do ambiente TSO.


6. O parâmetro DYNAMNBR=20

DYNAMNBR=20

Esse parâmetro está relacionado ao número de alocações dinâmicas que o ambiente TSO pode utilizar.

Durante a execução, o IKJEFT01, o command processor DSN ou programas chamados podem precisar alocar datasets dinamicamente.

Exemplos:

  • bibliotecas;

  • arquivos temporários;

  • arquivos de controle;

  • mensagens;

  • datasets de trabalho.

O valor:

20

costuma ser suficiente para execuções simples.

Em ambientes maiores aparecem valores como:

DYNAMNBR=50

ou:

DYNAMNBR=100

Não significa que o sistema abrirá imediatamente 20 datasets. É uma capacidade reservada para o ambiente.

Um valor insuficiente pode provocar falhas de alocação em execuções mais complexas.


7. A STEPLIB do Db2

//STEPLIB DD DSN=DSN910.SDSNLOAD,DISP=SHR

A STEPLIB informa as bibliotecas usadas na procura dos programas daquele step.

A biblioteca:

DSN910.SDSNLOAD

contém módulos relacionados ao Db2.

Entre eles podem existir componentes necessários para:

  • iniciar o command processor DSN;

  • usar o TSO Attachment Facility;

  • conectar-se ao subsistema;

  • carregar rotinas internas;

  • interagir com os serviços Db2.

O nome DSN910 pode indicar uma instalação antiga, uma versão ou apenas uma convenção local.

Não devemos presumir que o nome da biblioteca representa exatamente a versão atual do Db2. Muitas instalações mantêm nomes históricos para evitar alterar centenas de JCLs.

Contudo, é essencial que essa biblioteca seja compatível com o subsistema usado.

O subsistema do exemplo é:

DB9G

Se a SDSNLOAD não for a correta, podem surgir:

  • mensagens de conexão;

  • módulo não encontrado;

  • falhas no attachment;

  • abends;

  • incompatibilidade de nível.


8. DISP=SHR

Tanto a JOBLIB quanto a STEPLIB e o arquivo de entrada utilizam:

DISP=SHR

O parâmetro DISP descreve o estado e o tratamento do dataset.

SHR significa que o dataset já existe e pode ser compartilhado.

Exemplo:

//STEPLIB DD DSN=DSN910.SDSNLOAD,DISP=SHR

Essa biblioteca poderá ser usada simultaneamente por vários jobs.

Isso é normal para load libraries, pois dezenas ou centenas de aplicações podem carregar módulos da mesma biblioteca.

No arquivo de entrada:

//LISTCOPAC DD DSN=INFEF00.COPIA.MUNDO,DISP=SHR

o SHR indica leitura compartilhada.

Se o programa estivesse atualizando diretamente um dataset, talvez fosse necessário:

DISP=OLD

Mas para leitura QSAM, SHR é a escolha mais comum.


9. O DD LISTCOPAC

//LISTCOPAC DD DSN=INFEF00.COPIA.MUNDO,DISP=SHR

Essa linha liga um nome lógico a um dataset físico.

O nome lógico é:

LISTCOPAC

O dataset físico é:

INFEF00.COPIA.MUNDO

No programa COBOL provavelmente existe:

SELECT ARQUIVO-COPAC
    ASSIGN TO LISTCOPAC
    ORGANIZATION IS SEQUENTIAL
    ACCESS MODE IS SEQUENTIAL
    FILE STATUS IS WS-FILE-STATUS.

O COBOL conhece o arquivo pelo nome lógico. O JCL informa qual dataset real será usado.

Essa separação é poderosa.

O mesmo programa pode processar arquivos diferentes sem precisar ser recompilado.

Hoje:

//LISTCOPAC DD DSN=INFEF00.COPIA.MUNDO,DISP=SHR

Amanhã:

//LISTCOPAC DD DSN=INFEF00.COPIA.MUNDO.NOVO,DISP=SHR

O programa continua igual.

É o JCL que conecta a aplicação ao dado certo.


10. O que é QSAM?

QSAM significa Queued Sequential Access Method.

É um método de acesso para datasets sequenciais.

O programa COBOL executa comandos simples:

OPEN INPUT
READ
CLOSE

Mas o QSAM trabalha nos bastidores com:

  • buffers;

  • blocos;

  • movimentação de dados;

  • controle de fim de arquivo;

  • tratamento de registros;

  • acesso ao dispositivo;

  • otimização de entrada e saída.

Imagine um arquivo com registros de 100 bytes:

LRECL=100

O sistema não precisa necessariamente ler um registro físico por operação de disco.

Ele pode ler um bloco contendo vários registros:

BLKSIZE=27900

Nesse caso, um bloco pode conter 279 registros de 100 bytes.

O programa continua pedindo um registro por vez, mas o QSAM já trouxe vários registros para a memória.

Essa é a magia silenciosa do buffering.


11. Exemplo de definição COBOL

Um arquivo poderia ter esta estrutura:

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

    SELECT ARQ-COPAC
        ASSIGN TO LISTCOPAC
        ORGANIZATION IS SEQUENTIAL
        ACCESS MODE IS SEQUENTIAL
        FILE STATUS IS WS-FS-COPAC.

DATA DIVISION.
FILE SECTION.

FD  ARQ-COPAC
    RECORDING MODE IS F.

01  REG-COPAC.
    05 CP-CODIGO           PIC 9(05).
    05 CP-NOME             PIC X(40).
    05 CP-PAIS             PIC X(30).
    05 CP-POPULACAO        PIC 9(11).
    05 FILLER              PIC X(14).

O tamanho total seria:

5 + 40 + 30 + 11 + 14 = 100 bytes

Logo, o dataset deveria ter:

RECFM=FB
LRECL=100

Se o arquivo tiver LRECL=80, a definição estará incompatível.

O resultado pode ser:

  • erro de abertura;

  • registros truncados;

  • campos deslocados;

  • dados inválidos;

  • abend;

  • inserções incorretas no banco.


12. File Status: o sensor do arquivo

Todo programa COBOL profissional deveria usar FILE STATUS.

Exemplo:

01  WS-FS-COPAC         PIC XX.

Após o OPEN:

OPEN INPUT ARQ-COPAC

IF WS-FS-COPAC NOT = '00'
    DISPLAY 'ERRO NO OPEN DO ARQUIVO: ' WS-FS-COPAC
    MOVE 12 TO RETURN-CODE
    GOBACK
END-IF

Alguns estados comuns:

00 = operação concluída
10 = fim de arquivo
35 = arquivo não encontrado
39 = conflito de atributos
41 = arquivo já aberto
42 = arquivo não aberto
46 = tentativa inválida de READ

O status 39 merece atenção especial.

Ele pode ocorrer quando a definição física do arquivo não combina com o que o programa espera.

É o mainframe dizendo:

“Padawan, o arquivo existe, mas sua descrição não corresponde à realidade.”


13. O DD SYSTSPRT

//SYSTSPRT DD SYSOUT=*

O SYSTSPRT recebe mensagens do TSO e do command processor DSN.

É uma das saídas mais importantes para análise.

Ali podem aparecer:

  • início do DSN;

  • conexão com o subsistema;

  • processamento do comando RUN;

  • mensagens sobre PLAN;

  • falha na localização do programa;

  • retorno do ambiente Db2;

  • encerramento do command processor.

Quando o job falhar antes de entrar no programa COBOL, o SYSTSPRT deve ser uma das primeiras saídas examinadas.


14. O significado de SYSOUT=*

DD SYSOUT=*

Isso não significa “um arquivo chamado SYSOUT”.

SYSOUT=* envia a saída ao spool, usando normalmente a classe de saída definida pelo job.

Exemplo:

//SYSTSPRT DD SYSOUT=*

As mensagens poderão ser vistas no SDSF.

O asterisco significa, em termos práticos:

“Use a classe de saída padrão associada ao job.”

Também seria possível especificar uma classe:

//SYSTSPRT DD SYSOUT=X

A classe depende das regras da instalação.


15. O problema dos DDs duplicados

Na imagem aparecem duas linhas:

//SYSOUT DD SYSOUT=*
//SYSOUT DD SYSOUT=*

Esse é um provável erro.

Dentro do mesmo step, dois DD statements não devem possuir o mesmo DDNAME dessa maneira.

Se o programa precisa de duas saídas, use nomes diferentes:

//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*

Ou:

//RELATORI DD SYSOUT=*
//ERROS    DD SYSOUT=*

Os nomes devem corresponder ao que o programa espera.

Exemplo no COBOL:

SELECT ARQ-RELATORIO
    ASSIGN TO RELATORI.

SELECT ARQ-ERROS
    ASSIGN TO ERROS.

O JCL seria:

//RELATORI DD SYSOUT=*
//ERROS    DD SYSOUT=*

E se a intenção era concatenar?

A concatenação correta seria:

//ENTRADA  DD DSN=ARQUIVO.PARTE1,DISP=SHR
//         DD DSN=ARQUIVO.PARTE2,DISP=SHR

Observe que apenas a primeira linha possui DDNAME.

Portanto:

//SYSOUT DD SYSOUT=*
//SYSOUT DD SYSOUT=*

não é a maneira adequada de concatenar.


16. O DD SYSTSIN

//SYSTSIN DD *

O SYSTSIN fornece comandos ao ambiente TSO batch.

Tudo entre:

//SYSTSIN DD *

e:

/*

será entregue ao IKJEFT01.

No exemplo:

DSN SYSTEM(DB9G)
RUN PROGRAM(COBDB501) PLAN(HERP0001) -
    LIB('ADCD.Z112.USERLOAD')

Essas linhas não são JCL.

São comandos processados dentro do ambiente TSO/Db2.

Essa diferença é fundamental.

JCL:

//SYSTSIN DD *

Comando TSO:

DSN SYSTEM(DB9G)

Subcomando Db2:

RUN PROGRAM(COBDB501)

17. O comando DSN SYSTEM(DB9G)

DSN SYSTEM(DB9G)

O comando DSN inicia o command processor do Db2.

O parâmetro:

SYSTEM(DB9G)

identifica o subsistema desejado.

O nome de quatro caracteres:

DB9G

é o subsystem ID.

Em outros ambientes poderíamos encontrar:

DB2D
DB2T
DB2H
DB2P
D91A
DSN1

A convenção varia.

Por exemplo:

DB2D = desenvolvimento
DB2T = teste
DB2H = homologação
DB2P = produção

Mas essa nomenclatura não é uma regra do Db2. É apenas uma convenção possível.

Quando o comando é executado, o sistema tenta:

  1. localizar o subsistema;

  2. estabelecer o attachment;

  3. criar uma thread;

  4. validar o ambiente;

  5. preparar a execução do programa.

Se o subsistema estiver parado, o programa nem chegará a ser carregado.


18. O comando RUN PROGRAM

RUN PROGRAM(COBDB501)

O DSN recebe a ordem para executar o programa:

COBDB501

Esse nome deve corresponder ao load module ou program object gerado no link-edit.

O DSN não executa o fonte COBOL.

Ele procura algo como:

ADCD.Z112.USERLOAD(COBDB501)

O membro deve ser um executável válido.

Se o membro não existir, pode ocorrer uma mensagem de programa não encontrado ou até um abend S806, dependendo do ponto da falha.


19. A cláusula PLAN(HERP0001)

PLAN(HERP0001)

O PLAN representa o contexto de execução Db2 da aplicação.

Historicamente, o PLAN continha diretamente os DBRMs.

Nos ambientes modernos, é comum o PLAN apontar para PACKAGES:

PLAN
  ↓
PKLIST
  ↓
COLLECTION
  ↓
PACKAGE
  ↓
Seções SQL

O PLAN:

HERP0001

deve existir no subsistema DB9G.

Também precisa estar autorizado para o usuário que executa o job.

Caso contrário, podem surgir erros relacionados a:

  • autorização;

  • PLAN inexistente;

  • PACKAGE não localizado;

  • collection incorreta;

  • inconsistência entre programa e PACKAGE.


20. DBRM, PACKAGE e PLAN

Quando um programa COBOL contém SQL:

EXEC SQL
    INSERT INTO TB_COPAC
           (CODIGO, NOME, PAIS)
    VALUES (:CP-CODIGO, :CP-NOME, :CP-PAIS)
END-EXEC

o compilador COBOL não entende sozinho esse SQL.

Antes da compilação, ocorre o precompile Db2.

O precompiler produz dois resultados:

1. Fonte COBOL modificado
2. DBRM

O fonte modificado contém chamadas à interface Db2.

O DBRM contém as instruções SQL extraídas.

Fluxo completo:

COBOL + SQL
    ↓
PRECOMPILE
    ├── COBOL modificado
    └── DBRM
          ↓
      BIND PACKAGE
          ↓
       PACKAGE

Enquanto isso:

COBOL modificado
    ↓
COMPILER
    ↓
OBJECT MODULE
    ↓
LINK-EDIT
    ↓
LOAD MODULE

Na execução, o load module e o PACKAGE precisam pertencer à mesma geração lógica.


21. O clássico SQLCODE -818

O -818 ocorre quando o programa executável e o DBRM ou PACKAGE não possuem o mesmo consistency token.

Em linguagem Bellacosa:

O sabre de luz e o cristal kyber vieram de treinamentos diferentes.

Isso acontece quando:

  1. o programa é precompilado;

  2. é gerado um novo DBRM;

  3. o COBOL é compilado;

  4. o load module é atualizado;

  5. o PACKAGE antigo continua no Db2.

Ou o contrário:

  1. um novo PACKAGE é criado;

  2. o load module antigo continua na loadlib.

Resultado:

SQLCODE -818

A correção normalmente exige refazer o ciclo com os mesmos artefatos:

PRECOMPILE
COMPILE
LINK-EDIT
BIND PACKAGE

22. O SQLCODE -805

O -805 também é extremamente comum.

Ele indica que o Db2 não encontrou o PACKAGE necessário.

Possíveis causas:

  • PACKAGE não bindado;

  • collection errada;

  • PLAN não contém a collection;

  • nome do programa diferente;

  • ambiente errado;

  • PACKAGE removido;

  • load module promovido sem o BIND correspondente.

A mensagem geralmente fornece informações sobre:

  • localização;

  • collection;

  • package;

  • consistency token.

Esses dados devem ser analisados cuidadosamente.


23. A cláusula LIB

LIB('ADCD.Z112.USERLOAD')

A cláusula LIB informa a biblioteca onde o programa deve ser localizado.

Portanto:

RUN PROGRAM(COBDB501)
    PLAN(HERP0001)
    LIB('ADCD.Z112.USERLOAD')

significa:

Execute o programa COBDB501, utilizando o PLAN HERP0001, procurando o módulo na biblioteca ADCD.Z112.USERLOAD.

Essa instrução é importante porque a STEPLIB contém apenas a biblioteca Db2.

Sem a cláusula LIB, o programa da aplicação talvez não fosse encontrado.

Atenção à biblioteca antiga

A imagem também mostra:

//JOBLIB DD DSN=IBMUSER.CBL.LOADLIB,DISP=SHR

Temos então duas bibliotecas que podem conter o programa:

IBMUSER.CBL.LOADLIB
ADCD.Z112.USERLOAD

É importante confirmar onde está a versão correta.

Talvez exista:

IBMUSER.CBL.LOADLIB(COBDB501)

e também:

ADCD.Z112.USERLOAD(COBDB501)

Se a versão nova foi gravada na primeira biblioteca, mas o comando RUN aponta para a segunda, o job continuará executando o programa antigo.

Esse é um easter egg clássico do mainframe:

O código está correto, a compilação terminou com RC 0, mas o comportamento não mudou porque o job está carregando outra cópia do programa.

Para investigar, use ISPF 3.4 e compare:

  • data;

  • hora;

  • tamanho;

  • atributos;

  • usuário da última alteração.


24. O hífen de continuação

PLAN(HERP0001) -

O hífen informa que o comando continua na linha seguinte.

A continuação é:

LIB('ADCD.Z112.USERLOAD')

Sem o hífen, o DSN poderia tratar a primeira linha como um comando completo e a segunda como outro comando.

Uma versão bem formatada seria:

RUN PROGRAM(COBDB501) -
    PLAN(HERP0001)     -
    LIB('ADCD.Z112.USERLOAD')

O estilo depende do padrão da empresa, mas a legibilidade melhora bastante.


25. O comando END

O JCL da imagem não apresenta explicitamente:

END

É recomendável encerrar a sessão DSN:

//SYSTSIN DD *
  DSN SYSTEM(DB9G)
  RUN PROGRAM(COBDB501) PLAN(HERP0001) -
      LIB('ADCD.Z112.USERLOAD')
  END
/*

O fim do arquivo de comandos pode encerrar o command processor, mas o END deixa a intenção explícita.

É uma boa prática.


26. Exemplo completo de JCL corrigido

//CATPGM1 JOB (ACCT),'CARGA COBOL DB2',
//             CLASS=A,
//             MSGCLASS=X,
//             MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID
//*
//*-------------------------------------------------------------------*
//* PROGRAMA COBOL LE ARQUIVO QSAM E INSERE DADOS NO DB2
//*-------------------------------------------------------------------*
//EXECDB2 EXEC PGM=IKJEFT01,DYNAMNBR=20
//*
//* MODULOS DO DB2
//*
//STEPLIB DD DSN=DSN910.SDSNLOAD,DISP=SHR
//*
//* ARQUIVO SEQUENCIAL DE ENTRADA
//*
//LISTCOPAC DD DSN=INFEF00.COPIA.MUNDO,DISP=SHR
//*
//* SAIDAS DO AMBIENTE E DO PROGRAMA
//*
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*
//*
//* COMANDOS TSO E DB2
//*
//SYSTSIN DD *
  DSN SYSTEM(DB9G)
  RUN PROGRAM(COBDB501) PLAN(HERP0001) -
      LIB('ADCD.Z112.USERLOAD')
  END
/*
//

27. Explicação do cartão JOB

//CATPGM1 JOB (ACCT),'CARGA COBOL DB2',

CATPGM1 é o nome do job.

(ACCT)

representa informações contábeis da instalação.

'CARGA COBOL DB2'

é uma descrição.


CLASS=A

CLASS=A

Define a classe de execução.

A classe pode determinar:

  • prioridade;

  • initiator;

  • limites;

  • ambiente;

  • políticas de scheduling.

O significado de A varia conforme a instalação.


MSGCLASS=X

MSGCLASS=X

Define a classe das mensagens de saída.

Ela influencia onde e como o spool será tratado.


MSGLEVEL=(1,1)

MSGLEVEL=(1,1)

Controla o nível de detalhes registrado no spool.

O primeiro valor controla a impressão das instruções JCL.

O segundo controla mensagens de alocação e execução.


NOTIFY=&SYSUID

NOTIFY=&SYSUID

Solicita que o usuário que submeteu o job seja notificado quando ele terminar.

&SYSUID é substituído pelo ID do usuário.


28. Exemplo de programa COBOL

       IDENTIFICATION DIVISION.
       PROGRAM-ID. COBDB501.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT ARQ-COPAC
               ASSIGN TO LISTCOPAC
               ORGANIZATION IS SEQUENTIAL
               ACCESS MODE IS SEQUENTIAL
               FILE STATUS IS WS-FS-COPAC.

       DATA DIVISION.
       FILE SECTION.

       FD  ARQ-COPAC
           RECORDING MODE IS F.

       01  REG-COPAC.
           05 CP-CODIGO           PIC 9(05).
           05 CP-NOME             PIC X(40).
           05 CP-PAIS             PIC X(30).
           05 CP-POPULACAO        PIC 9(11).
           05 FILLER              PIC X(14).

       WORKING-STORAGE SECTION.

       01  WS-FS-COPAC            PIC XX.
       01  WS-FIM-ARQUIVO         PIC X VALUE 'N'.
           88 FIM-ARQUIVO               VALUE 'S'.

       01  WS-CONTADORES.
           05 WS-LIDOS            PIC 9(09) COMP-3 VALUE ZERO.
           05 WS-INSERIDOS        PIC 9(09) COMP-3 VALUE ZERO.
           05 WS-REJEITADOS       PIC 9(09) COMP-3 VALUE ZERO.
           05 WS-COMMIT           PIC 9(05) COMP-3 VALUE ZERO.

       01  WS-SQLCODE-AUX         PIC -9(09).

           EXEC SQL
               INCLUDE SQLCA
           END-EXEC.

       PROCEDURE DIVISION.

       0000-PRINCIPAL.

           PERFORM 1000-INICIALIZAR

           PERFORM 2000-PROCESSAR
               UNTIL FIM-ARQUIVO

           PERFORM 9000-FINALIZAR

           GOBACK.

29. Inicialização do programa

       1000-INICIALIZAR.

           DISPLAY 'INICIO DO PROGRAMA COBDB501'

           OPEN INPUT ARQ-COPAC

           IF WS-FS-COPAC NOT = '00'
               DISPLAY 'ERRO NO OPEN LISTCOPAC: ' WS-FS-COPAC
               MOVE 12 TO RETURN-CODE
               GOBACK
           END-IF

           PERFORM 2100-LER-ARQUIVO.

A primeira leitura é realizada na inicialização.

Esse padrão evita que o programa execute o processamento com um registro não carregado.


30. Leitura e processamento

       2000-PROCESSAR.

           ADD 1 TO WS-LIDOS

           PERFORM 3000-VALIDAR-REGISTRO

           IF CP-CODIGO IS NUMERIC
               PERFORM 4000-INSERIR-DB2
           ELSE
               ADD 1 TO WS-REJEITADOS
               DISPLAY 'CODIGO INVALIDO: ' CP-CODIGO
           END-IF

           PERFORM 2100-LER-ARQUIVO.

A leitura:

       2100-LER-ARQUIVO.

           READ ARQ-COPAC
               AT END
                   SET FIM-ARQUIVO TO TRUE
               NOT AT END
                   CONTINUE
           END-READ

           IF WS-FS-COPAC NOT = '00'
              AND WS-FS-COPAC NOT = '10'
               DISPLAY 'ERRO DE LEITURA: ' WS-FS-COPAC
               PERFORM 8000-ROLLBACK
               MOVE 12 TO RETURN-CODE
               GOBACK
           END-IF.

O status 10 representa fim de arquivo e não deve ser tratado como erro.


31. O INSERT Db2

       4000-INSERIR-DB2.

           EXEC SQL
               INSERT INTO TB_COPAC
               (
                   CODIGO,
                   NOME,
                   PAIS,
                   POPULACAO
               )
               VALUES
               (
                   :CP-CODIGO,
                   :CP-NOME,
                   :CP-PAIS,
                   :CP-POPULACAO
               )
           END-EXEC

           EVALUATE SQLCODE
               WHEN ZERO
                   ADD 1 TO WS-INSERIDOS
                   ADD 1 TO WS-COMMIT

               WHEN -803
                   ADD 1 TO WS-REJEITADOS
                   DISPLAY 'CHAVE DUPLICADA: ' CP-CODIGO

               WHEN OTHER
                   MOVE SQLCODE TO WS-SQLCODE-AUX
                   DISPLAY 'ERRO SQL: ' WS-SQLCODE-AUX
                   DISPLAY 'REGISTRO: ' CP-CODIGO
                   PERFORM 8000-ROLLBACK
                   MOVE 12 TO RETURN-CODE
                   GOBACK
           END-EVALUATE

           IF WS-COMMIT >= 1000
               PERFORM 7000-COMMIT
           END-IF.

32. Por que não fazer apenas um COMMIT no final?

Imagine uma carga de dez milhões de registros.

Se o programa executar um único COMMIT, poderá manter durante horas:

  • locks;

  • espaço de log;

  • páginas modificadas;

  • recursos;

  • unidade de trabalho gigantesca.

Se ocorrer erro no registro 9.999.999, o rollback poderá desfazer tudo.

Uma estratégia mais segura é:

COMMIT a cada 1.000 registros

Ou:

COMMIT a cada 5.000 registros

O valor ideal depende do ambiente.

Não existe um número mágico.

É preciso considerar:

  • volume;

  • concorrência;

  • log;

  • índices;

  • tempo de recuperação;

  • SLA;

  • restart;

  • regras de negócio.

Rotina:

       7000-COMMIT.

           EXEC SQL
               COMMIT
           END-EXEC

           IF SQLCODE NOT = ZERO
               DISPLAY 'ERRO NO COMMIT: ' SQLCODE
               MOVE 12 TO RETURN-CODE
               GOBACK
           END-IF

           MOVE ZERO TO WS-COMMIT.

33. ROLLBACK

       8000-ROLLBACK.

           EXEC SQL
               ROLLBACK
           END-EXEC

           DISPLAY 'ROLLBACK EXECUTADO'.

O rollback desfaz alterações realizadas desde o último commit.

Mas atenção: ele não desfaz tudo desde o início do programa se já ocorreram commits intermediários.

Exemplo:

1.000 registros → COMMIT
1.000 registros → COMMIT
500 registros → erro → ROLLBACK

Nesse caso:

  • os primeiros 2.000 permanecem;

  • os últimos 500 são desfeitos.


34. Finalização

       9000-FINALIZAR.

           IF WS-COMMIT > ZERO
               PERFORM 7000-COMMIT
           END-IF

           CLOSE ARQ-COPAC

           DISPLAY '--------------------------------'
           DISPLAY 'REGISTROS LIDOS     : ' WS-LIDOS
           DISPLAY 'REGISTROS INSERIDOS : ' WS-INSERIDOS
           DISPLAY 'REGISTROS REJEITADOS: ' WS-REJEITADOS
           DISPLAY 'FIM DO PROGRAMA COBDB501'
           DISPLAY '--------------------------------'.

Esses totais serão enviados ao SYSOUT ou à saída padrão do Language Environment, dependendo da configuração.

Eles são fundamentais para auditoria.


35. Códigos de retorno

O programa pode usar:

MOVE 0 TO RETURN-CODE

para sucesso.

Outros códigos comuns:

RC 0  = sucesso
RC 4  = sucesso com aviso
RC 8  = erro de aplicação
RC 12 = erro grave
RC 16 = falha crítica

Esses valores são convenções. A empresa pode definir outros padrões.

Um scheduler pode usar o retorno:

RC <= 4  → continuar
RC >= 8  → interromper fluxo

36. Possíveis falhas

JCL ERROR

Causa provável:

//SYSOUT DD SYSOUT=*
//SYSOUT DD SYSOUT=*

Correção: usar DDNAMEs distintos.


S806

O programa não foi encontrado.

Verificar:

ADCD.Z112.USERLOAD(COBDB501)

S013

Pode estar relacionado à incompatibilidade de atributos do dataset.

Verificar:

  • RECFM;

  • LRECL;

  • BLKSIZE;

  • modo de abertura;

  • definição FD.


SQLCODE -803

Chave duplicada.

O programa tentou inserir um valor único já existente.


SQLCODE -805

PACKAGE não encontrado.

Verificar:

  • collection;

  • BIND PACKAGE;

  • PLAN;

  • consistency token.


SQLCODE -818

Load module e PACKAGE incompatíveis.

Refazer compilação e BIND de forma sincronizada.


SQLCODE -904

Recurso indisponível.

Pode existir:

  • tablespace parado;

  • utility pendente;

  • objeto em estado restritivo;

  • problema de storage.


SQLCODE -911

Deadlock ou timeout com rollback.

A aplicação precisa registrar:

  • chave;

  • SQLCODE;

  • unidade de trabalho;

  • momento do erro.


SQLCODE -922

Problema de autorização ou conexão.

Verificar permissões para:

  • PLAN;

  • PACKAGE;

  • tabela;

  • operação INSERT;

  • subsistema.


37. Como investigar no SDSF

Depois de submeter o job, abra:

SDSF

Depois:

ST

Localize o job e abra com S.

Analise na seguinte ordem:

JESJCL

Mostra o JCL interpretado.

Útil para detectar:

  • erro de sintaxe;

  • DD duplicado;

  • PROC expandida;

  • símbolos substituídos.

JESYSMSG

Mostra mensagens do sistema.

Procure por prefixos:

IEF
IEC
IGD
ICH

SYSTSPRT

Mostra mensagens do TSO e DSN.

SYSOUT

Mostra os DISPLAY do COBOL.

CEEDUMP

Mostra informações de falhas do Language Environment.

SYSUDUMP

Pode conter detalhes de abend e registradores.


38. Easter egg: o programa antigo que nunca morre

Um dos problemas mais misteriosos do mainframe ocorre assim:

  1. o programador altera o fonte;

  2. compila com RC 0;

  3. submete o job;

  4. o comportamento antigo continua;

  5. compila novamente;

  6. nada muda;

  7. começa a desconfiar do compilador, do Db2 e talvez da própria realidade.

A causa:

O load module foi gravado em uma biblioteca,
mas o RUN está usando outra.

Exemplo:

Novo:
IBMUSER.CBL.LOADLIB(COBDB501)

Executado:
ADCD.Z112.USERLOAD(COBDB501)

O mainframe não está errado.

Ele apenas obedeceu exatamente ao que foi pedido.

Essa é uma das grandes lições do IBM Z:

O sistema raramente faz o que imaginamos. Ele faz o que realmente declaramos.


39. O grande mapa da missão

INFEF00.COPIA.MUNDO
          │
          │ LISTCOPAC
          ▼
     Programa COBOL
       COBDB501
          │
          │ EXEC SQL INSERT
          ▼
      PLAN HERP0001
          │
          ▼
        PACKAGE
          │
          ▼
       Db2 DB9G
          │
          ▼
       TB_COPAC

Ao redor dessa execução, estão:

JES2
IKJEFT01
SDSNLOAD
TSO Attachment
Language Environment
QSAM
RACF
SDSF
Logs do Db2

Nada acontece isoladamente.


Conclusão: poucas linhas, muitas engrenagens

O JCL apresentado é um excelente exemplo da filosofia mainframe: comandos pequenos podem coordenar estruturas gigantescas.

Uma linha como:

RUN PROGRAM(COBDB501) PLAN(HERP0001)

carrega décadas de evolução tecnológica.

Ela conecta:

  • um executável COBOL;

  • um ambiente TSO batch;

  • um subsistema Db2;

  • um PLAN;

  • PACKAGES;

  • SQL estático;

  • um arquivo sequencial;

  • QSAM;

  • segurança;

  • logging;

  • controle transacional.

Para o programador COBOL padawan, a principal lição é não observar o JCL como uma simples receita de execução.

Cada DD representa um contrato.

LISTCOPAC → contrato com o arquivo
STEPLIB   → contrato com as bibliotecas
SYSTSIN   → contrato com o TSO
SYSTSPRT  → contrato com as mensagens
PLAN      → contrato com o Db2
LIB       → contrato com o executável
COMMIT    → contrato com a integridade

Quando esses contratos estão alinhados, milhões de registros podem ser processados com precisão.

Quando um deles está errado, o sistema pode responder com um JCL ERROR, um S806, um -805, um -818 ou um silencioso arquivo lido com layout incorreto.

O verdadeiro domínio do mainframe não vem apenas de decorar comandos.

Ele nasce quando entendemos a jornada completa:

Fonte
  → Precompile
  → Compile
  → Link-edit
  → DBRM
  → BIND PACKAGE
  → BIND PLAN
  → JCL
  → IKJEFT01
  → DSN
  → COBOL
  → QSAM
  → Db2
  → COMMIT
  → SDSF

E assim, diante da tela verde, com uma caneca de café ao lado, o padawan percebe que aquele pequeno JCL não é apenas um arquivo de comandos.

É a porta de entrada para uma das arquiteturas de processamento corporativo mais robustas já construídas.

sexta-feira, 30 de dezembro de 2022

😶‍🌫️ 2022: O Ano da Ressaca Pandêmica

 


😶‍🌫️ 2022: O Ano da Ressaca Pandêmica

Por ElJefe — crônicas do mundo pós-COVID para padawans cansados


Padawan, respire fundo.
Chegamos a 2022, o ano em que o planeta acordou com uma ressaca coletiva — física, mental e espiritual.
Depois de dois anos de caos, isolamento e paranoia, o mundo queria festejar… mas ainda tropeçava nas próprias cicatrizes.

Era o começo do novo normal, aquele que ninguém pediu, mas todos tiveram que aceitar.


🕊️ O Mundo Sai da Caverna

As máscaras começaram a cair — literalmente.
Bares reabriram, estádios voltaram a gritar, aviões voltaram a voar.
Mas havia algo estranho no ar (e não era o vírus, desta vez):
as pessoas voltaram diferentes.

O silêncio de 2020 e 2021 tinha deixado marcas.
Muitos não sabiam mais socializar, outros tinham medo de tudo,
e alguns fingiam que nada tinha acontecido — como se a pandemia fosse um pesadelo coletivo convenientemente esquecido.

“O corpo se cura mais rápido que a mente, padawan.”


💉 A Ciência Triunfa… Mas a Desinformação Fica

As vacinas funcionaram.
O mundo começou a se proteger em massa, e os hospitais esvaziaram.
Mas o inimigo invisível mudou de forma: agora era a mentira.

Fake news continuavam, mas com novos temas:
microchips, mutações zumbis, conspirações políticas.
Era o mesmo script, só mudava o vilão da semana.

O algoritmo, esse novo imperador do caos, percebeu uma coisa:
a verdade cansa, mas a teoria da conspiração diverte.

E assim, o pós-pandemia virou o palco de uma nova guerra —
a guerra pela narrativa.


🧠 A Crise Silenciosa: Saúde Mental

Em 2022, o vírus saiu das manchetes e deu lugar a outro tipo de pandemia — a da ansiedade.
Empresas voltaram ao trabalho híbrido, mas ninguém sabia mais o que era equilíbrio.
Gente exausta, emocionalmente drenada, e uma avalanche de “coachs de resiliência” pipocando em todo canto.

As redes sociais, que haviam sido o refúgio do isolamento, agora mostravam um novo tipo de contágio:
a comparação, o cansaço e o medo de não estar “vivendo o suficiente” depois de dois anos trancado.

Padawan, 2022 ensinou que:

“Nem toda cura vem de um remédio — às vezes, vem de uma conversa sincera e de um bom café.”


🕹️ O Novo Normal: Híbrido, Digital, Estranho

O trabalho remoto virou rotina, o QR Code virou idioma, e o metaverso surgiu prometendo mundos paralelos onde ninguém pegava vírus.
Enquanto isso, escolas, empresas e governos tentavam se adaptar a um planeta que já não cabia mais nos moldes antigos.

O “novo normal” era um Frankenstein social:
um pouco analógico, um pouco digital, um pouco cansado.

Mas, como bons padawans da era moderna, aprendemos a navegar —
mesmo com o GPS quebrado.


💔 O Luto Coletivo

Entre as risadas dos reencontros e o som dos brindes, havia silêncio.
Milhões tinham partido, e nem todos tiveram chance de se despedir.
2022 foi o ano em que o luto veio atrasado.
O mundo chorou em silêncio — não por falta de lágrimas, mas por falta de tempo.

E nesse silêncio, nasceu um novo tipo de consciência:
a de que viver é urgente.


☕ Epílogo de ElJefe

2022 não foi o fim da pandemia — foi o fim da inocência.
Descobrimos que a vida não volta a ser o que era,
porque nós não somos mais quem éramos.

A humanidade tropeçou, caiu, chorou, e mesmo assim… continuou.
E como todo padawan que passa por uma prova difícil, saímos diferentes:
menos ingênuos, mais atentos, e talvez — só talvez — um pouco mais sábios.

“O vírus mostrou que somos frágeis.
A solidão mostrou que somos humanos.
E a esperança mostrou que ainda vale a pena lutar.”

quinta-feira, 29 de dezembro de 2022

Sobrevivemos a pandemia!!!!!

 


A convivencia com 4 adultos foi dificeil, o isolamento social, ficar presos num espaço confinado. Não poder sair a rua, tomar sol e viver uma vida normal foi dificil.

Atritos aconteceram, mas também momentos unicos e marcantes. Obrigado pela companhia de vocês e este poste ficara para o sempre, como testuma de dois anos que nunca terminavam e por fim acabou.

Viva a vacina, viva por estarmos vivos e espantarmos o fantasma da morte. Perdemos entes queridos no caminho, mas enfim ca estamos.

Obrigado.


Brasil 2022: quando o sistema saiu do modo emergência, aplicou o patch certo — e o legado voltou a fazer sentido

 

Bellacosa Mainframe e o recomeço após a pandemia do covid

Brasil 2022: quando o sistema saiu do modo emergência, aplicou o patch certo — e o legado voltou a fazer sentido

Meu nono ano pós-retorno ao Brasil foi 2022. Um ano que não começou leve, mas terminou diferente. Não foi redenção, nem milagre. Foi algo mais raro em sistemas grandes: estabilização real depois do caos. Para quem viveu doze anos na Europa e atravessou, já no Brasil, uma sequência quase didática de colapsos, 2022 teve gosto de restart limpo, ainda com arquivos corrompidos, mas com o sistema respirando outra vez.

Depois de 2020 e 2021, isso já era muita coisa.

A vacina: o patch que salvou o sistema

A vacina salvou vidas. Isso não é metáfora, é fato técnico. Em linguagem de mainframe: foi o patch crítico que impediu o shutdown definitivo. Não resolveu tudo, não apagou traumas, mas devolveu algo essencial — previsibilidade mínima.

Quando a vacinação avançou, algo mudou no ar. As pessoas voltaram a sair sem culpa. A respirar sem medo constante. A planejar de novo, mesmo que em curto prazo. Para quem viveu na Europa, onde a vacina também simbolizou retomada, foi nítido perceber: sem ela, o Brasil teria entrado em colapso social irreversível.

O sistema humano voltou a responder.

Economia: não prosperidade, mas movimento

Economicamente, 2022 não foi abundância — foi movimento. E depois de anos de paralisia, movimento já é sinal de vida. Pequenos negócios retomaram, serviços reapareceram, projetos voltaram à mesa.

O home-office deixou de ser improviso e virou arquitetura. Muita gente percebeu que não precisava mais estar fisicamente presa a centros caros, congestionados e emocionalmente desgastantes. Para quem tinha vivido fora, isso soava familiar: trabalho orientado a entrega, não a presença.

O Brasil começou, tardiamente, a entender algo básico do mundo moderno.

Sociedade: menos grito, mais cansaço — e alguma lucidez

Socialmente, 2022 foi menos explosivo que os anos anteriores. Não porque os problemas sumiram, mas porque as pessoas estavam cansadas demais para berrar o tempo todo. E o cansaço, às vezes, produz lucidez.

Houve polarização, sim. Mas também houve uma vontade silenciosa de seguir em frente. De reconstruir rotinas. De não viver mais em estado permanente de alerta.

O tecido social ainda estava rasgado — mas já não sangrava o tempo todo.

Cultura: reaprendendo a criar

Culturalmente, 2022 foi um recomeço tímido. Eventos voltaram. Encontros reapareceram. A arte saiu do modo sobrevivência e voltou, devagar, ao modo criação.

O Brasil reaprendeu algo essencial: cultura não é luxo, é manutenção do sistema. Sem ela, a máquina enlouquece.

Educação, DIO e o inesperado renascimento do legado

E aqui veio a grande surpresa do ano.

Enquanto muita gente ainda apostava apenas no “novo pelo novo”, 2022 mostrou algo que todo veterano de mainframe já sabia: sistemas críticos não são descartados — são mantidos.

A DIO e outras plataformas começaram a oferecer cursos gratuitos, acessíveis, práticos. Gente que jamais teria acesso a formação técnica começou a estudar de casa. Home-office, cursos online, capacitação assíncrona — tudo isso abriu portas reais.

E então aconteceu o impensável para quem só conhece tecnologia por hype:
o mainframe voltou ao centro do jogo.

Choveu vaga de COBOL. Literalmente.

Bancos, seguradoras, governos, empresas globais — todos dependentes de sistemas escritos décadas atrás — perceberam que não tinham operadores suficientes. O legado não morreu. Ele sobreviveu a todas as modas. E agora pedia gente que soubesse ler, entender e manter código crítico.

Para mim, isso teve gosto de justiça histórica.

O renascimento do mainframe: quando experiência vira ativo

Depois de anos em que “antigo” era tratado como sinônimo de “obsoleto”, 2022 lembrou o óbvio: antigo é o que continua funcionando quando tudo o resto falha.

COBOL não voltou por nostalgia. Voltou por necessidade. Voltou porque sistemas que pagam salários, aposentadorias, benefícios e movimentam trilhões não podem cair.

E, de repente, quem carregava conhecimento profundo deixou de ser peso e voltou a ser pilar.

Todo operador de mainframe sorriu em silêncio.

População: machucada, mas de pé

O povo em 2022 ainda estava machucado. Mentalmente, financeiramente, emocionalmente. Mas estava de pé. Mais cauteloso. Menos iludido. Um pouco mais sábio — no sentido duro da palavra.

A esperança voltou, mas não era mais ingênua. Era técnica. Condicionada. Baseada em evidência, não em promessa.

Nono ano pós-retorno: reconciliação com o tempo

Em 2022, pela primeira vez desde que voltei ao Brasil, senti algo próximo de reconciliação. Não com o país idealizado. Mas com o país real. Complexo. Difícil. Injusto em muitos pontos. Mas vivo.

E comigo mesmo também. Entendi que voltar não foi erro nem acerto simples. Foi parte do job.

Epílogo: a lição final do ano

2022 ensinou uma verdade que só sistemas grandes revelam depois de crises profundas:

o futuro não elimina o passado — ele o integra.

O Brasil só voltou a respirar porque aplicou ciência, tecnologia, trabalho remoto, educação acessível —
e porque o legado estava lá, silencioso, sustentando tudo.

O sistema não virou perfeito.
Mas voltou a funcionar com propósito.

E todo veterano de mainframe sabe:
quando o legado resiste,
é sinal de que ainda há muito sistema pela frente.

quarta-feira, 28 de dezembro de 2022

Da Baixa Plataforma ao IBM Mainframe O Guia Definitivo para Desenvolvedores que Desejam Migrar para o IBM Z

 

Bellacosa Mainframe da baixa para a alta plataforma a jornada do padawan a stack mainframe

☕ Um Café no Bellacosa Mainframe

Da Baixa Plataforma ao IBM Mainframe

O Guia Definitivo para Desenvolvedores que Desejam Migrar para o IBM Z

Você não está voltando ao passado. Está descobrindo onde a Engenharia de Software aprendeu a nunca falhar.

Há uma pergunta que recebo praticamente todas as semanas.

"Vale a pena aprender Mainframe em 2026?"

Minha resposta continua exatamente a mesma.

Sim. E talvez hoje faça ainda mais sentido do que há dez anos.

Enquanto novas linguagens surgem todos os anos, existe uma plataforma que continua processando boa parte da economia mundial com disponibilidade próxima de 100%.

Essa plataforma é o IBM Z.

Mas este artigo não é sobre máquinas.

É sobre pessoas.

Sobre desenvolvedores que dominam Java, Python, C#, Delphi, Go, Rust, Kotlin, C++, Visual Basic e outras tecnologias e desejam entender como esse conhecimento pode abrir as portas do universo Mainframe.

Pegue um café.

Vamos conversar.


Antes de tudo: esqueça os mitos

Existe uma enorme quantidade de desinformação sobre Mainframe.

Você provavelmente já ouviu alguma destas frases:

  • "Mainframe morreu."

  • "Só existem sistemas antigos."

  • "COBOL é uma linguagem ultrapassada."

  • "Ninguém mais aprende isso."

  • "Tudo foi para a nuvem."

Na prática, basta observar quem movimenta bilhões de transações diariamente:

  • bancos;

  • seguradoras;

  • bolsas de valores;

  • companhias aéreas;

  • operadoras de cartão;

  • governos;

  • empresas de logística.

Em muitos casos, o coração desses negócios continua sendo o IBM Z.

Não porque seja antigo.

Mas porque funciona extraordinariamente bem.


Você não está trocando de profissão

Quem vem da baixa plataforma costuma imaginar que precisará começar do zero.

Não precisa.

Você continua sendo desenvolvedor.

Continua resolvendo problemas.

Continua escrevendo software.

A diferença está na prioridade.

Na baixa plataforma normalmente pensamos em:

  • experiência do usuário;

  • frameworks;

  • componentes;

  • bibliotecas;

  • deploy contínuo;

  • microsserviços.

Na alta plataforma pensamos em:

  • continuidade do negócio;

  • disponibilidade;

  • integridade dos dados;

  • desempenho previsível;

  • recuperação de falhas;

  • processamento em larga escala.

O objetivo muda.

A engenharia evolui.


O IBM Z não compete com a nuvem

Um erro comum é imaginar que Cloud e Mainframe disputam espaço.

Na realidade eles trabalham juntos.

Hoje encontramos ambientes onde:

  • APIs REST expõem programas COBOL;

  • Java executa no z/OS;

  • Linux roda dentro do IBM Z;

  • Kubernetes conversa com aplicações corporativas;

  • OpenShift integra workloads;

  • IA analisa dados produzidos pelo Mainframe;

  • Git e VS Code fazem parte do dia a dia.

O IBM Z moderno é uma plataforma integrada ao restante da arquitetura corporativa.


Esqueça a pergunta "Qual linguagem é melhor?"

Essa pergunta perde completamente o sentido no mundo corporativo.

Cada tecnologia resolve problemas diferentes.

Python resolve problemas.

Java resolve problemas.

Rust resolve problemas.

COBOL resolve problemas.

A verdadeira pergunta é:

Qual tecnologia oferece menor risco para aquele negócio?

É exatamente aí que o Mainframe se destaca.


O que realmente muda?

Muito menos do que você imagina.

Você continuará trabalhando com:

  • variáveis;

  • estruturas condicionais;

  • repetições;

  • funções;

  • módulos;

  • arquivos;

  • bancos de dados;

  • APIs;

  • mensagens.

O que muda é a forma de organizar esses componentes.


As maiores mudanças de mentalidade

Disponibilidade

Na Web um servidor pode reiniciar.

Num banco isso pode significar milhões de reais.


Performance previsível

Não basta ser rápido.

É preciso manter o mesmo desempenho durante milhões de transações.


Integridade

Cada registro possui valor financeiro.

Cada atualização precisa ser consistente.


Auditoria

Tudo precisa ser rastreável.


Segurança

Segurança deixa de ser funcionalidade.

Passa a ser requisito básico.


O ecossistema IBM Z

Aprender apenas COBOL é conhecer apenas uma pequena parte da plataforma.

Você encontrará tecnologias como:

  • COBOL

  • JCL

  • CICS

  • Db2

  • IMS

  • VSAM

  • MQ

  • RACF

  • TSO/ISPF

  • SDSF

  • JES2

  • REXX

  • z/OS

  • z/OS Connect

  • Zowe

  • Git

  • VS Code

  • OpenShift

  • Ansible

  • Java

  • Python

É um ecossistema completo.


A melhor estratégia de aprendizagem

Não tente aprender tudo ao mesmo tempo.

Minha recomendação é:

Primeira etapa

  • Conceitos do Mainframe

  • z/OS

  • Dataset

  • Batch

  • Online

Segunda etapa

  • TSO/ISPF

  • JCL

  • SDSF

Terceira etapa

  • COBOL

Quarta etapa

  • Db2

  • VSAM

Quinta etapa

  • CICS

Depois disso você poderá seguir para:

  • APIs

  • MQ

  • DevOps

  • Git

  • Zowe

  • Java

  • Python

  • IA aplicada ao IBM Z


Escolha sua linguagem de origem

Preparei uma série mostrando como cada tecnologia conversa com o universo IBM Z.

☕ Java → COBOL

https://eljefemidnightlunch.blogspot.com/2022/01/do-java-ao-cobol-no-ibm-z-um-guia-para.html

Para quem já desenvolve aplicações corporativas.


☕ Python → COBOL

https://eljefemidnightlunch.blogspot.com/2022/02/de-python-ao-cobol-no-ibm-z-voce-nao.html

Automação, produtividade e integração.


☕ C# → COBOL

https://eljefemidnightlunch.blogspot.com/2022/03/de-c-ao-cobol-no-ibm-z-voce-nao-esta.html

A ponte entre aplicações Microsoft e IBM Z.


☕ Visual Basic → COBOL

https://eljefemidnightlunch.blogspot.com/2022/04/do-visual-basic-ao-cobol-no-ibm-z-voce.html

Quem domina regras de negócio já possui uma enorme vantagem.


☕ Go → COBOL

https://eljefemidnightlunch.blogspot.com/2022/05/de-go-ao-cobol-no-ibm-z-voce-nao-esta.html

Simplicidade encontra estabilidade.


☕ Rust → COBOL

https://eljefemidnightlunch.blogspot.com/2022/06/de-rust-ao-cobol-no-ibm-z-voce-nao-esta.html

Segurança de memória aplicada aos sistemas mais críticos do mundo.


☕ C++ → COBOL

https://eljefemidnightlunch.blogspot.com/2022/07/de-c-ao-cobol-no-ibm-z-voce-nao-esta.html

Arquitetura, desempenho e controle.


☕ Kotlin → COBOL

https://eljefemidnightlunch.blogspot.com/2022/08/de-kotlin-ao-cobol-no-ibm-z-voce-nao.html

A produtividade moderna chegando aos sistemas corporativos.


☕ Delphi → COBOL

https://eljefemidnightlunch.blogspot.com/2022/09/de-delphi-ao-cobol-no-ibm-z-voce-nao.html

RAD, regras de negócio e engenharia corporativa.


Conselhos para quem está começando

✔ Não compare COBOL com Java.

✔ Não compare z/OS com Windows.

✔ Não tente aprender tudo em uma semana.

✔ Leia programas antigos.

✔ Entenda o negócio antes do código.

✔ Aprenda a usar o teclado.

✔ Estude JCL cedo.

✔ Aprenda a interpretar mensagens do sistema.

✔ Não tenha medo da tela preta.

✔ Nunca pare de estudar.


Conclusão

O IBM Z continua sendo uma das plataformas mais importantes da computação mundial.

Ele não representa o passado da tecnologia.

Representa décadas de evolução em disponibilidade, segurança, desempenho e confiabilidade.

Se você domina qualquer linguagem moderna, já possui o ingrediente mais importante: sabe resolver problemas.

Aprender Mainframe significa adicionar uma nova perspectiva à sua carreira e compreender como funcionam alguns dos sistemas mais críticos do planeta.

No Bellacosa Mainframe acreditamos que o melhor desenvolvedor não é aquele que conhece apenas uma plataforma.

É aquele que consegue transitar entre todas elas, levando consigo boas práticas, curiosidade e respeito pela engenharia de software.

 

sexta-feira, 23 de dezembro de 2022

Java no IBM Z: Como Java Conversa com COBOL, DB2, CICS e o Mundo Mainframe na Prática

 

Bellacosa Mainframe como java conversa com o mainframe

☕ Um Café no Bellacosa Mainframe

Java no IBM Z: Como Java Conversa com COBOL, DB2, CICS e o Mundo Mainframe na Prática

"O Java não chegou para substituir o COBOL. Ele chegou para conversar com ele."

Existe uma lenda que circula há muitos anos entre profissionais de TI.

Ela diz que existem dois mundos completamente diferentes.

De um lado está o mundo Mainframe.

Do outro está o mundo Java.

Na realidade... isso nunca foi verdade.

Hoje, milhares de bancos, seguradoras, governos e bolsas de valores executam aplicações onde Java, COBOL, CICS, DB2, MQ, z/OS Connect e APIs REST trabalham juntos no mesmo IBM Z.

A pergunta deixou de ser:

"Java ou COBOL?"

e passou a ser:

"Como fazer ambos trabalharem juntos?"

Pegue seu café porque hoje vamos abrir a tampa do motor do IBM Z.


A chegada do Java ao Mainframe

Quando Java apareceu em 1995, muitos profissionais de Mainframe olharam com desconfiança.

"Uma linguagem interpretada?"

"Rodando em máquina virtual?"

"Orientada a objetos?"

Parecia impossível competir com COBOL compilado.

Mas havia um detalhe importante.

Java tinha uma vantagem gigantesca.

Escrever uma vez, executar em qualquer lugar

A JVM (Java Virtual Machine) permitia que o mesmo programa funcionasse em:

  • Windows

  • Linux

  • Unix

  • AIX

  • IBM Z

A IBM rapidamente percebeu que clientes desejariam executar Java perto dos dados.

E onde estavam os dados?

No DB2.

No VSAM.

No IMS.

No CICS.

No MQ.

Ou seja...

Java precisava ir até o Mainframe.

Não fazia sentido mover bilhões de registros para outro servidor.

Muito mais eficiente era mover o processamento.


O nascimento do Java no z/OS

A IBM portou a JVM para o z/OS.

Depois vieram:

  • IBM SDK for Java

  • JZOS

  • JDBC para DB2

  • CICS Java

  • Liberty

  • WebSphere

  • OpenJ9 JVM

Hoje Java é cidadão de primeira classe dentro do IBM Z.


A arquitetura moderna

Imagine um banco.

Cliente Web

      │

 REST API

      │

 Liberty

      │

 Java

      │

 JDBC

      │

 DB2

Agora imagine outro fluxo.

Cliente

↓

CICS

↓

Programa Java

↓

Programa COBOL

↓

DB2

Ou ainda

Java

↓

MQ

↓

COBOL

↓

IMS

Ou

Java

↓

z/OS Connect

↓

CICS

↓

COBOL

↓

VSAM

Perceba.

O Java raramente trabalha sozinho.

Ele normalmente atua como a camada de integração.


JDBC

JDBC significa:

Java Database Connectivity

É a API padrão do Java para conversar com bancos de dados.

No Mainframe ela conversa principalmente com o DB2.


Exemplo

Connection conn =
DriverManager.getConnection(
"jdbc:db2://servidor:446/BANCO",
"usuario",
"senha");

A partir daí...

PreparedStatement ps =
conn.prepareStatement(
"SELECT NOME,SALDO FROM CLIENTE WHERE ID=?");
ps.setInt(1,100);
ResultSet rs = ps.executeQuery();

Enquanto houver registros

while(rs.next()){

System.out.println(
rs.getString("NOME"));

}

Isso parece simples.

Mas por trás existe uma enorme infraestrutura.


O Driver JDBC

O Driver JDBC entende dois idiomas.

Ele fala Java.

E fala DB2.

É literalmente um tradutor.

Java

↓

Driver JDBC

↓

DRDA

↓

DB2

O desenvolvedor escreve SQL.

O Driver transforma isso em chamadas compreendidas pelo DB2.


O Prepared Statement

No Mainframe quase nunca usamos:

Statement

Preferimos:

PreparedStatement

Por quê?

Porque:

  • reutiliza plano de acesso

  • melhora performance

  • evita SQL Injection

  • reduz parsing

Exemplo

SELECT *
FROM CLIENTE
WHERE CPF=?

O ponto de interrogação representa um parâmetro.


Como Java conversa com DB2

Internamente ocorre algo semelhante.

Java

↓

JDBC

↓

DRDA

↓

DB2 Thread

↓

Buffer Pool

↓

Tablespace

O Java nunca lê páginas do banco.

Quem faz isso é o DB2.


Como COBOL acessa DB2

No COBOL usamos:

EXEC SQL

SELECT NOME

INTO :WS-NOME

FROM CLIENTE

END-EXEC.

No Java:

String nome=
rs.getString("NOME");

O objetivo é exatamente o mesmo.

A tecnologia muda.


Conversão de tipos

Essa é uma das maiores dúvidas.

Como converter tipos COBOL para Java?

COBOL

PIC X(30)

Java

String

COBOL

PIC X

Java

char

ou

String

COBOL

PIC 9(4)

Java

int

COBOL

PIC 9(9)

Java

long

COBOL

PIC S9(9)V99 COMP-3

Java

BigDecimal

Nunca utilize:

double

para dinheiro.

Sempre:

BigDecimal

Datas

COBOL

PIC X(10)

2026-07-01

Java

LocalDate

ou

LocalDateTime

Boolean

COBOL tradicional não possui boolean.

Normalmente usa:

"S"

"N"

ou

1

0

No Java

boolean

Estruturas COBOL

Imagine

01 CLIENTE.

   05 ID.

   05 NOME.

   05 SALDO.

No Java

class Cliente{

int id;

String nome;

BigDecimal saldo;

}

Observe a semelhança.

O Java apenas encapsula os dados dentro de uma classe.


OO versus Procedural

COBOL

LER CLIENTE

↓

VALIDAR

↓

ATUALIZAR

↓

GRAVAR

Fluxo procedural.


Java

Cliente

↓

objeto

↓

métodos

↓

atributos

Em vez de funções espalhadas,

o comportamento fica dentro do objeto.


Classe

public class Cliente{

private String nome;

private BigDecimal saldo;

public void sacar(){

}

}

A classe reúne:

  • dados

  • comportamento


O que seria uma estrutura COBOL equivalente?

WORKING-STORAGE

↓

PROCEDURE DIVISION

↓

PARÁGRAFOS

A ideia é semelhante.

Só muda a organização.


Como Java chama COBOL?

Existem diversas formas.

CICS

Java

↓

EXEC CICS LINK

↓

Programa COBOL

JNI

Java pode chamar código nativo.


MQ

Java envia mensagem.

COBOL recebe.


REST

Java chama uma API exposta pelo COBOL.


Stored Procedures

DB2 executa procedimento COBOL.

Java apenas chama.


CICS

Imagine um caixa eletrônico.

O Java recebe uma requisição REST.

POST

/saque

Java valida.

Depois

EXEC CICS LINK

para

SAQ001

escrito em COBOL.

O COBOL atualiza saldo.

Retorna.

Java transforma em JSON.

Cliente recebe resposta.

Tudo acontece em poucos milissegundos.


JSON

O Java trabalha naturalmente com JSON.

Exemplo

{
 "id":100,
 "nome":"Maria",
 "saldo":2500
}

Classe

Cliente

Bibliotecas como Jackson fazem:

Objeto

JSON

e

JSON

Objeto

automaticamente.


XML

Antes do JSON predominava XML.

<cliente>

<nome>Maria</nome>

</cliente>

Ainda muito utilizado em:

SOAP

WebServices

Integrações legadas.


Conversão COBOL para JSON

Suponha

01 CLIENTE.

05 NOME.

05 CPF.

05 SALDO.

Java monta

{
 "nome":"",
 "cpf":"",
 "saldo":0
}

O mapeamento costuma ser feito por:

  • Jackson

  • JAXB

  • JSON-B


Datasets

Java também pode acessar datasets.

Mas normalmente utiliza:

JZOS.

Exemplo

HLQ.CLIENTES.MASTER

O Java lê registros do dataset.

Sem necessidade de FTP.


VSAM

Também pode acessar

  • KSDS

  • ESDS

  • RRDS

através de APIs específicas.


Arquivos Sequenciais

Java consegue ler datasets RECFM FB.

Cada registro torna-se um array de bytes.

Depois converte.

Bytes

↓

String

↓

Objeto Java

EBCDIC versus ASCII

Outro ponto crítico.

Mainframe usa:

EBCDIC.

Java trabalha internamente em Unicode.

Então existe conversão automática.

EBCDIC

↓

Unicode

↓

String

Sem isso os caracteres apareceriam ilegíveis.


Batch Java

Pouca gente sabe.

Java também roda Batch.

JCL

//STEP1 EXEC PGM=JVMLDM86

ou

BPXBATCH

executando

java MinhaClasse

Exemplo

//JAVA EXEC PGM=BPXBATCH
//STDENV DD *
JAVA_HOME=/usr/lpp/java
/*

O Java executa como qualquer programa batch.

Pode:

  • ler datasets

  • acessar DB2

  • gerar arquivos

  • enviar MQ

  • consumir APIs


Java Online

Dentro do CICS.

Ou Liberty.

Recebe milhares de requisições simultâneas.


JSP

Nos anos 2000 a IBM utilizou muito:

JSP

↓

Servlet

↓

Java

↓

DB2

A página dinâmica misturava HTML com Java.

Exemplo

<%=cliente.getNome()%>

Hoje é menos comum.

Frameworks modernos predominam.

Mas muitos sistemas bancários ainda utilizam JSP.


Servlets

O Servlet recebe a requisição.

HTTP

↓

Servlet

↓

Java

↓

DB2

Depois devolve HTML.

Ou JSON.


APIs REST

Hoje a arquitetura mais comum é

Angular

↓

REST

↓

Java

↓

COBOL

↓

DB2

O usuário nem imagina que existe COBOL.


LinuxONE

Agora entra um personagem muito importante.

O LinuxONE.

Ele compartilha praticamente a mesma arquitetura do IBM Z.

Executa:

  • Linux

  • Containers

  • Docker

  • Kubernetes

  • OpenShift

  • Java

  • IA

Tudo extremamente próximo do z/OS.

Isso reduz:

  • latência

  • tráfego de rede

  • custo

Imagine

LinuxONE

↓

Java

↓

MQ

↓

z/OS

↓

COBOL

Tudo dentro do mesmo hardware.


OpenJ9

A JVM da IBM foi otimizada.

Ela consome menos memória.

Melhora Garbage Collection.

Aproveita processadores IBM Z.


zIIP

Aqui está um dos grandes diferenciais.

Grande parte do processamento Java pode utilizar processadores zIIP.

Resultado:

mais desempenho.

Menor custo de licenciamento.

É uma das razões pelas quais muitas empresas migraram workloads Java para o IBM Z.


Um fluxo completo

Imagine uma transferência bancária.

Celular

↓

HTTPS

↓

API REST

↓

Liberty

↓

Java

↓

Validação

↓

EXEC CICS LINK

↓

COBOL

↓

DB2

↓

COMMIT

↓

Resposta COBOL

↓

Objeto Java

↓

JSON

↓

Cliente

Perceba que cada tecnologia faz aquilo em que é especialista.

  • Java oferece APIs, integração, orientação a objetos e desenvolvimento web.

  • COBOL executa regras de negócio consolidadas ao longo de décadas.

  • CICS coordena as transações com alta disponibilidade.

  • DB2 garante consistência, integridade e desempenho.

  • JCL agenda e executa processos batch.

  • MQ desacopla sistemas e permite comunicação assíncrona.

  • LinuxONE hospeda aplicações Java, microsserviços e containers próximos aos dados.

  • IBM Z fornece segurança, escalabilidade, criptografia e confiabilidade.

Não existe competição entre essas tecnologias. Existe colaboração.


Procedural x Orientado a Objetos: uma visão para quem vem do COBOL

Para um programador COBOL, pense da seguinte forma:

No COBOL você cria um programa que manipula registros.

No Java você cria um objeto que representa aquele registro e sabe operar sobre ele.

No COBOL:

LER CLIENTE
VALIDAR CLIENTE
ATUALIZAR CLIENTE
GRAVAR CLIENTE

No Java:

Cliente cliente = repositorio.buscar(id);
cliente.validar();
cliente.atualizarSaldo(valor);
repositorio.salvar(cliente);

A regra de negócio continua praticamente a mesma. O que muda é a forma de organizá-la.


O futuro

Nos últimos anos surgiram novas tecnologias como:

  • Jakarta EE

  • Spring Boot

  • Quarkus

  • Open Liberty

  • z/OS Connect EE

  • APIs REST

  • GraphQL

  • Kafka

  • OpenShift

  • Red Hat Ansible Automation Platform

  • IA Generativa integrada ao IBM Z

Mesmo assim, o núcleo dos sistemas bancários continua sendo, em muitos casos, o mesmo:

  • COBOL processando regras críticas.

  • CICS coordenando milhões de transações.

  • DB2 armazenando dados.

  • Java expondo serviços modernos.

  • LinuxONE executando aplicações cloud-native próximas ao ambiente z/OS.


Conclusão

Durante muitos anos, criou-se a falsa ideia de que Java substituiria o COBOL. A história mostrou o contrário. O IBM Z evoluiu para unir o melhor dos dois mundos.

O COBOL permanece imbatível na execução de regras de negócio críticas e estáveis. O Java tornou-se a ponte para APIs REST, aplicações web, microsserviços, integração com nuvem, processamento orientado a objetos e experiências digitais modernas.

Hoje, quando um cliente consulta o saldo pelo aplicativo do banco, dificilmente percebe a sofisticada cadeia tecnológica envolvida. Um JSON percorre uma API REST hospedada em Open Liberty, passa por classes Java, utiliza JDBC para acessar o DB2 ou aciona um programa COBOL via CICS. Em segundos, o resultado retorna ao celular com segurança, integridade transacional e disponibilidade próxima de 100%.

Esse é o verdadeiro espírito do IBM Z moderno: não substituir o legado, mas ampliá-lo. Java, COBOL, CICS, DB2, JCL, LinuxONE, APIs e containers deixaram de ser tecnologias concorrentes e passaram a formar um único ecossistema. É justamente essa capacidade de integrar décadas de investimento com inovação contínua que mantém o Mainframe como a espinha dorsal de alguns dos maiores sistemas financeiros, governamentais e corporativos do planeta. E, para o profissional de Mainframe que aprende Java, abre-se uma nova fronteira: compreender não apenas como cada tecnologia funciona isoladamente, mas como elas conversam para sustentar o mundo digital moderno.


Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...