Migration Assistée par LLM

Le cas Sicas

La migration de Sicas comporte 3 défis majeurs

Sécurité

Qualité

Déploiement

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

Choix des outils

Pour la migration nous avons sélectionné

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

Choix des outils

Pour la migration nous avons sélectionné

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

Le plan

1

2

3

Java 6 ⟶ Java 21

Spring ⟶ Spring Boot

Mise au standard de qualité

Everybody has a plan until they get punched in the mouth

Première étape
migration avec Amazon Q Transform

Durée de l'étape : Une heure

Amazon Q Transform

Durée de l'étape : Une heure

Amazon Q Transform

Amazon Q Transform

Transformation Hub

Il permet de suivre la progression du job.

Amazon Q Transform

Summary

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.

Amazon Q Transform

Summary

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.)

 

Durée de l'étape :
Une heure

1 bis, terminer la migration

Correction des tests

Méthodo

Correction des tests

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>

Correction des CVE

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.

Nous avons corrigé la totalité des 60 CVEs

Durée de l'étape :
le reste de la journée (6h)

Deuxième étape
Spring ⟶ Spring Boot

Obstacle : JNDI

JNDI nécessite un serveur d'appli
Spring Boot = pas de serveur d'appli

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

Configuration XML ⟶ Java

Claude est super fort pour ça !

Configuration XML ⟶ Java

Il analyse l’intention du la configuration

Configuration XML ⟶ Java

Et la restitue
dans un fichier
en Java

Durée de l'étape
8 jours (JH)

Troisième étape
Mise au standard
de qualité

Augmentation de la couverture

Méthodo

Augmentation de la couverture

Claude comprends bien les contextes imbriqués dans des balises XML

# 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>

Augmentation de la couverture

Kaizen

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>

Augmentation de la couverture

Courbe Sonar

Augmentation de la couverture

Apprentissages

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"

Next steps

On a un fichier par stratégie de test

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.

Durée de l'étape
14 jours (JH)

Bilan

Capitalisation du savoir

Standing on the shoulders of giants

Cette expérience est une opportunité pour écrire un nouveau standard.

https://www.notion.so/m33/Ecrire-des-tests-unitaires-et-d-int-gration-avec-un-LLM-22a8f3776f4f80cba8cbc4041ed013a0

 

Pour l'ajouter à la collection de nos standards sur l'IA

https://www.notion.so/m33/Partnering-with-AI-395ef37df344425aaaadf61266768bf1

 

 

Réflexions

Prompt engineering

Prompt crafting

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 ?

Prompt engineering

Prompt crafting

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

Merci !

Votre avis compte !