La version Java 1.6 est obsolète et comporte de nombreuses failles de sécurité
Le code de Sicas n’est testé qu’à 1,8%.
Plus personne ne maîtrise le fonctionnel
Des adaptations sont nécessaires :
- Spring ⟶ Spring Boot
- Corriger les issues Sonar
- Dépendances obsolètes
- Couverture de test
Amazon Q Transform solution clé en main de migration de codebase d’une version obsolète (6) de Java vers une version LTS moderne (17 ou 21). Il est disponible sous la forme d’un plugin JetBrains.
La solution utilise :
OpenRewrite
Outil de migration déterministe
Claude 3.7
Cline est une solution de GenAI agentique avec choix du modèle.
Le modèle Claude 4 Opus est un des plus performants pour la génération de code grâce à son attention à l’architecture générale du produit.
Nous l’utilisons dans VSCode.
https://binaryverseai.com/best-llm-for-code-in-2025-claude-4-leads/#2-comprehensive-comparison-of-leading-code-ll-ms
https://writingmate.ai/blog/best-llm-ai-coding
Java 6 ⟶ Java 21
Spring ⟶ Spring Boot
Mise au standard de qualité
Il permet de suivre la progression du job.
Rapport détaillé de la transformation effectuée
et de ce que le LLM n’a pas pu faire.
Limitation : pour vérifier son travail il builde dans son datacenter.
⇒ il n’a pas accès aux libs propriétaires.
✅ Done
Java 6 ⟶ Java 21
Spring 3 ⟶ Spring 6 (quasi)
Code métier intact (un peu trop)
⏳ Reste à faire
Des librairies propriétaires obsolètes à remplacer
Des librairies OSS obsolètes n’ont pas pu être migrées
car plus maintenues (unitils.org)
Utiliser les structure modernes de Java 21
(records, enhanced for-loops, try-with-resources, Streams, etc.)
Après plusieurs itérations nous sommes arrivés à un ensemble efficace de règles
# Convert test to Junit4-compatible version
## Goal
Change this Java test file to be compatible with JUnit4 leveraging the vintage library.
## Rules
<rule>In the imports, replace import org.junit.jupiter.api.Assertions; with import org.junit.Assert;</rule>
<rule>In the code, find the Assertions and replace them with Assert</rule>
<rule>In the imports, replace import org.junit.jupiter.api.Disabled; with import org.junit.Ignore;</rule>
<rule>In the code, find the Disable and replace them with Ignore</rule>
<rule>In the imports, replace import org.junit.jupiter.api.Test; with import org.junit.Test;</rule>
<rule>Don't change the "import static org.junit.jupiter.api.Assertions.assertThrows;"</rule>
<rule>Don't change assertThrows in the code</rule>
Le LLM en a corrigé la moitié en une heure en mettant à jour la codebase.
L’autre moitié a été corrigée au cas par cas “à la main” pendant le reste de la journée en mettant à jour les versions des dépendances.
Je ne savais pas comment résoudre le problème.
Claude me l’a expliqué et donné des pistes de résolution.
🐤
Canard en caoutchouc qui parle
📚
Et qui sait beaucoup de choses
# Objective
Test JPA Entity in order to maximize test coverage with a Spring Data Jpa Test.
<rule>
When an entity is fetch from the database its setters are implicitly invoked.
Make sure they are invoked with various values so edge-cases are tested.
<example>
```java
var entity = new Entity();
entity.setId(ID);
entity.setValue("value with strange characters: %$?");
...
// Then
assertTrue(found.isPresent());
assertEquals("value with strange characters: %$?", found.get().getValue());
```
</example>
</rule>
Carefully read the following instructions.
Then ask what class these instruction should be applied to.
# Objective
<rule>
Create test classes that can run in isolation of any external system.
Example of external system:
- Databases. Use in-memory HSQLDB
- Web Services. Use MockServer library to stub the behavior of Web Services
</rule>
<rule>
Test all public methods of the class.
</rule>
<rule>
Tests must maximize test coverage.
All reachable branches of execution must be covered by a test method
</rule>
<rule>
Edge-cases must be tested.
For each parameter of a tested method, test the behavior of the tested method when
- if the parameter is a reference, test when the argument is null
- if the parameter is a String, test when the argument is the empty String `""`
- is the parameter is a number, test when the argument is negative, zero, positive
The nominal case must also be tested
- When the arguments are all valid
</rule>
<rule>
All test methods that test the same testes class method must be grouped in a nester class.
The nested class in annotated with @Nested
</rule>
<rule>
Test must use JUnit5
</rule>
<rule>
The test is an integration test and the test class must be annotated with @SpringBootTest
</rule>
<rule>
Do not mock simple java beans.
Juste instantiate them and set their test values with their mutators or their constructor arguments accordingly
<example>
Don't do this:
```java
Entity entityMock = mock(Entity.class);
when(entityMock.getValue()).thenReturn("A Value");
```
Do this instead:
```java
Entity testEntity = new EntityImpl();
testEntity.setValue("A value");
```
</example>
</rule>
<rule>
For operations on the file system, use the JimFS library and select Linux as the file system type.
</rule>
<rule>
Start by creating test setup in each test methods.
Then factorized setup in @BeforeEach methods at the nested class level when the setup is used by all test methods of the nested class
Then factorize setup in @BeforeEach at the test root class when it is used in all nested classes
</rule>
<rule>
Use modern Java syntax like text blocks, SequencedCollections.
</rule>
Le LLM interprète l'intention du code
(vs: lit l'implémentaiton)
⚠️ Prendre soin du nommage !
✅ Permet de découvrir les écarts entre intention et implémentation
(A.K.A. les bugs)
❌ Ne sait pas faire "copier-coller"
Pour l’instant c’est l’humain qui sélectionne les instructions
à appliquer.
Car ce choix est instinctif ➡ on est C3.
En définissant clairement les critères de sélection
on passerait C4 ➡ on pourrait automatiser aussi cette partie.
Cette expérience est une opportunité pour écrire un nouveau standard.
Pour l'ajouter à la collection de nos standards sur l'IA
https://www.notion.so/m33/Partnering-with-AI-395ef37df344425aaaadf61266768bf1
Des règles qu’on assemble pour en faire des instructions
pour une machine 🤔
Est-ce que ce ne serait pas un langage de programmation de plus ?
En fait cette idée n’est pas originale
On appelle ça un langage de 5è génération
problem-solving using constraints given to the program, rather than using an algorithm written by a programmer – Wikipedia