# Especificação do Formato de Serialização ## 1. Visão Geral Este documento descreve as estratégias de serialização para a comunicação entre processos no sistema de simulação de tráfego distribuído. A serialização é necessária para transmitir objetos Java através de sockets entre diferentes processos (cruzamentos, coordenador, dashboard). ## 2. Requisitos ### 2.1 Objetos a Serializar Os principais objetos que precisam ser serializados são: - **Vehicle**: Contém estado completo do veículo (id, tipo, rota, métricas) - **Message**: Container para todas as mensagens entre processos - **Estatísticas**: Dados agregados dos cruzamentos e semáforos ### 2.2 Requisitos Funcionais - **Integridade**: Todos os dados devem ser preservados durante a serialização/desserialização - **Compatibilidade**: Suporte para evolução de classes (adicionar campos) - **Performance**: Latência mínima para não impactar a simulação - **Depuração**: Capacidade de inspecionar mensagens facilmente ### 2.3 Requisitos Não-Funcionais - Tamanho da mensagem otimizado - Fácil manutenção e extensibilidade - Compatibilidade com ferramentas de monitorização --- ## 3. Comparação: Java Serialization vs JSON ### 3.1 Java Serialization #### Vantagens ✅ 1. **Nativo do Java** - Sem dependências externas - Suporte built-in na JVM - Integração direta com Serializable 2. **Preservação de Tipos** - Mantém tipos Java exatos - Serializa grafo completo de objetos - Suporte automático para herança 3. **Performance de Escrita** - Serialização binária mais rápida - Menos overhead de conversão - ObjectOutputStream otimizado 4. **Facilidade de Implementação** - Basta implementar Serializable - Controle fino com serialVersionUID - Métodos customizados: writeObject/readObject #### Desvantagens ❌ 1. **Acoplamento Java** - Apenas entre aplicações Java - Dificulta interoperabilidade futura - Formato proprietário 2. **Tamanho das Mensagens** - Formato binário verboso - Inclui metadata de classes - 2-3x maior que JSON compacto 3. **Depuração Difícil** - Formato binário não legível - Necessita ferramentas especiais - Difícil inspecionar mensagens 4. **Problemas de Segurança** - Vulnerabilidades conhecidas (CVEs) - Desserialização insegura - Necessita validação cuidadosa 5. **Evolução de Classes** - serialVersionUID requer gestão manual - Quebra compatibilidade facilmente - Difícil manter versões diferentes #### Métricas Estimadas ``` Tamanho Médio: 400-600 bytes (Vehicle completo) Latência: 0.5-1ms (serialização + rede local) Throughput: ~10,000 msgs/s ``` --- ### 3.2 JSON (com Gson/Jackson) #### Vantagens ✅ 1. **Legibilidade Humana** - Formato texto simples - Fácil depuração - Inspecionável com ferramentas comuns 2. **Interoperabilidade** - Padrão universal - Facilita integração futura - Dashboard web, APIs, etc. 3. **Tamanho Otimizado** - Formato compacto - ~40% menor que Java Serialization - Compressão opcional (gzip) 4. **Evolução Flexível** - Campos opcionais nativos - Backward/forward compatibility - Versionamento natural 5. **Ferramentas e Ecossistema** - Bibliotecas maduras (Gson, Jackson) - Validação com JSON Schema - Suporte a logs estruturados 6. **Segurança** - Sem execução de código - Validação mais simples - Menos vetores de ataque #### Desvantagens ❌ 1. **Dependência Externa** - Necessita biblioteca (Gson/Jackson) - Aumenta tamanho do JAR - Possível quebra de dependência 2. **Performance de Conversão** - Parsing de texto - Reflexão Java - ~20-30% mais lento que binário 3. **Tipos Perdidos** - Necessita type hints - Problemas com genéricos - Enums requerem atenção 4. **Memória** - String temporárias - Maior uso de heap - GC mais frequente #### Métricas Estimadas ``` Tamanho Médio: 250-350 bytes (Vehicle completo) Latência: 0.8-1.5ms (conversão + rede local) Throughput: ~8,000 msgs/s ``` --- ## 4. Decisão e Recomendação ### 4.1 Análise de Contexto **Características do Projeto:** - Sistema distribuído Java-only (curto prazo) - Comunicação intra-rede local (baixa latência) - Volume moderado de mensagens (~100-1000/s) - Necessidade de depuração durante desenvolvimento - Potencial expansão futura (dashboard web) ### 4.2 Recomendação: **JSON (Gson)** #### Justificativa 1. **Desenvolvimento e Depuração** 🔍 - A fase atual do projeto requer debugging extensivo - JSON facilita inspeção de mensagens - Logs legíveis sem ferramentas especiais 2. **Manutenibilidade** 🔧 - Mais fácil para equipe aprender/modificar - Evolução de protocolo mais simples - Menos problemas de compatibilidade 3. **Extensibilidade** 🚀 - Dashboard web futuramente - APIs REST potenciais - Integração com ferramentas de monitorização 4. **Performance Aceitável** ⚡ - Diferença de latência irrelevante (< 1ms) - Volume de mensagens não é crítico - Rede local minimiza overhead 5. **Segurança** 🔒 - Evita vulnerabilidades de Java Serialization - Validação mais simples e segura ### 4.3 Quando Usar Java Serialization Java Serialization seria preferível se: - Performance crítica (> 100k msgs/s) - Objetos muito complexos com referências circulares - Garantia de ambiente Java puro permanente - Necessidade de preservar estado exato (locks, transient) --- ## 5. Implementação Recomendada ### 5.1 Arquitetura de Serialização ``` ┌─────────────────────────────────────────┐ │ Application Layer │ │ (Vehicle, Message, Statistics) │ └─────────────────┬───────────────────────┘ │ ┌─────────────────▼───────────────────────┐ │ Serialization Interface │ │ - serialize(Object): byte[] │ │ - deserialize(byte[], Class): T │ └─────────────────┬───────────────────────┘ │ ┌─────────┴─────────┐ │ │ ┌───────▼──────┐ ┌────────▼─────────┐ │ JsonSerializer│ │JavaSerializer │ │ (Gson-based) │ │(ObjectStream) │ └───────────────┘ └──────────────────┘ ``` ### 5.2 Estrutura de Mensagens JSON #### Exemplo 1: Transferência de Veículo ```json { "messageId": "a3c5e7f9-1234-5678-90ab-cdef12345678", "type": "VEHICLE_TRANSFER", "senderId": "Cr1", "destinationId": "Cr2", "timestamp": 1729595234567, "payload": { "id": "V123", "type": "LIGHT", "entryTime": 15.7, "route": ["Cr1", "Cr2", "Cr5", "S"], "currentRouteIndex": 1, "totalWaitingTime": 3.2, "totalCrossingTime": 1.8 } } ``` #### Exemplo 2: Atualização de Estatísticas ```json { "messageId": "b4d6e8f0-2345-6789-01bc-def123456789", "type": "STATS_UPDATE", "senderId": "Cr3", "destinationId": "Dashboard", "timestamp": 1729595234789, "payload": { "intersectionId": "Cr3", "queueLengths": { "North": 5, "South": 3, "East": 7, "West": 2 }, "vehiclesProcessed": 142, "averageWaitTime": 4.5 } } ``` ### 5.3 Biblioteca Escolhida: **Gson** **Por que Gson (não Jackson)?** - ✅ Mais simples e leve - ✅ Menos configuração necessária - ✅ API mais intuitiva para iniciantes - ✅ Melhor para modelos simples (nosso caso) - ⚠️ Jackson seria melhor para: streaming, performance extrema, binding complexo --- ## 6. Plano de Implementação ### Fase 1: Setup - [x] Adicionar dependência Gson ao pom.xml - [ ] Criar interface `MessageSerializer` - [ ] Implementar `JsonMessageSerializer` - [ ] Implementar `JavaMessageSerializer` (fallback) ### Fase 2: Adapters - [ ] Criar adaptadores Gson para classes do modelo - [ ] Configurar serialização customizada se necessário - [ ] Implementar testes unitários ### Fase 3: Integração - [ ] Integrar serializer nos sockets - [ ] Adicionar logs de mensagens - [ ] Implementar mecanismo de versionamento ### Fase 4: Otimização (Opcional) - [ ] Implementar compressão (gzip) - [ ] Pool de serializers - [ ] Métricas de performance --- ## 7. Estrutura de Arquivos ``` src/main/java/sd/ ├── serialization/ │ ├── MessageSerializer.java # Interface comum │ ├── JsonMessageSerializer.java # Implementação Gson │ ├── JavaMessageSerializer.java # Implementação nativa │ ├── SerializerFactory.java # Factory pattern │ └── adapters/ # Type adapters Gson │ ├── VehicleAdapter.java │ └── MessageAdapter.java └── network/ ├── MessageSocket.java # Wrapper para socket └── MessageProtocol.java # Protocolo de comunicação ``` --- ## 8. Considerações Finais ### 8.1 Boas Práticas 1. **Versionamento**: Incluir campo `version` nas mensagens 2. **Validação**: Validar mensagens após desserialização 3. **Logging**: Logar mensagens em desenvolvimento (desabilitar em produção) 4. **Exceções**: Tratar erros de serialização gracefully 5. **Testes**: Testar serialização round-trip para todas as classes ### 8.2 Monitorização - Tamanho médio de mensagens - Latência de serialização/desserialização - Taxa de erros de serialização - Throughput de mensagens ### 8.3 Documentação Cada tipo de mensagem deve ser documentado com: - Propósito - Estrutura JSON - Exemplo - Sender/Receiver esperado - Comportamento em caso de erro --- ## 9. Referências - [Gson User Guide](https://github.com/google/gson/blob/master/UserGuide.md) - [Java Serialization Specification](https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html) - [JSON Schema](https://json-schema.org/) - [Effective Java - Item 87: Consider using a custom serialized form](https://www.oreilly.com/library/view/effective-java/9780134686097/) --- **Documento criado em**: 22 de outubro de 2025 **Versão**: 1.0 **Autor**: Equipa SD - Trabalho Prático