Le but du projet
Xplain est d'écrire une application Web qui permet d'expliquer les
erreurs de compilation et même dans un second temps de les corriger en utilisant un LLM
(parmi un choix d'au moins 3 LLMs)
L'application
Xplain est composée d'un
back-end écrit en Java offrant
différents services REST permettant de créer, visualiser et compiler/exécuter des classes Java.
Et d'un
front-end écrit en JavaScript.
L’application doit permettre...
-
De demander à compiler une classe Java à partir de son code source et à fournir
une explication de chaque erreur de compilation.
Pour obtenir une explication l'utilisateur pourra choisir parmi au moins 3 choix de LLM différents
(au moins un lent qui fourni de meilleure explication et un rapide qui fourni de moins bonne explication).
-
D'afficher la liste de l'ensemble des explications préalablement demandées dans l'ordre chronologique,
la demande d'explication la plus récente d'abord.
Chaque explication doit afficher les 3 premières lignes de la classe dont l'explication
a déjà été faite dans le passé pour qu'il soit facile de retrouver une ancienne explication.
En termes d'interface graphique, votre application doit être composée de deux écrans.
Un premier écran qui affiche la liste des précédentes explication avec un gros bouton plus (+)
qui permet d'ajouter le code d'une nouvelle classe qui une fois compilé
doit expliquer les erreurs de compilation à l'aide d'un LLM sélectionné (à vous de choisir le bon défaut).
L'affichage du diagnostique du LLM doit s'afficher au fur et à mesure.
Un second écran qui affiche la classe, les erreurs de compilations et les explications pour chaque erreur.
Technologies à utiliser
-
Vous devez utiliser Maven comme outil de build et IntelliJ comme IDE,
et la version 23 de Java.
-
Les test unitaires Java doivent être effectués avec JUnit 5.11.0, vous pouvez vous référer au
guide d'utilisation.
Chaque classe classe Java doit avoir une classe de test correspondante (pour au moins 80%) du projet.
-
Pour la sérialisation/dé-sérialisation JSON des requêtes, vous utiliserez une API de parsing JSON
Jackson 2.17.2
-
Pour interagir avec des LLMs locaux (le LLM doit tourner sur le serveur), vous devrez pour chaque LLM
- Choisir un moteur de LLM (llama.cpp, ONXX runtime, jlama, etc)
- Choisir quelle librairie de bindings Java vous allez utiliser (pour les moteurs pas écrits en Java)
- Choisir quel LLM vous allez utiliser pour ce runtime (au format GGUF, ONXX, safe tensor, etc)
Note: en aucun cas, vous ne devez faire tourner un autre serveur que votre server d'API pour exécuter
le LLM (on veut une architecture simple).
-
Utiliser l'API
javax.tools.JavaCompiler
pour intéragir avec le compilateur (sans lancer une nouvelle VM).
Pour implanter les différents services REST, votre application doit utiliser une des technos
(c'est moi qui choisi pas vous) ci-dessous.
Attention à bien faire la différence entre les versions AOT ou JVM et les versions
synchrone et asynchrone (reactive) des APIs !
Vous configurerez votre serveur pour qu'il utilise des threads virtuelles.
Pour l'API REST, les entrées et les sorties JSON doivent utiliser des records si possible.
Pour la mapping Object / Relational, i.e voir une ligne d'une table de BDD comme un objet Java.
Il y a deux implantations, une à base d'Hibernate qui peut être utilisée directement soit par
l'intermédiaire de la spécification JPA (Jakarta Persistence API).
Attention, l'ancienne version de la Jakarta Persistence API s'appelle la Java Persistence API,
les deux ont le même acronyme JPA. On veut la nouvelle version donc la version Jakarta.
Pour le
front-end web, vous avez besoin d'un framework graphique
Note : le front-end doit être "buildé" aussi en utilisant
Maven (un seul POM pour front et le back),
vous aurez peut-être besoin de plugin Maven spécifique pour cela.
Note2: vous avez besoin de
npm pour la partie build, mais pas à l'exécution !
Vous pouvez de plus, utiliser une librairie spéciale pour la gestion de l'affichage du tableau pourvu qu'elle
soit adaptée à votre framework (pas de react-grid si vous devez utiliser svelte).
Attention: lors du déploiement, vous ne devez pas utiliser nodejs comme serveur Web, car vous avez
déjà un serveur Web qui sert l'API donc il peut aussi servir les pages statiques de votre librarie JS.
Bien sûr, pour le build, vous pouvez utiliser nodejs et npm pour construire votre application web.
Pour vous aidez à avoir de belles pages, vous allez aussi utiliser une bibliothèque qui vous aide
pour la partie CSS
L'application a besoin d'une base de données, mais vu le volume de données, pas forcément d'une
"vrai" base de données, nous utiliserons donc des bases de données
embedded.
L'intérêt d'une BDD
embedded est qu'elle est prête à l'emploi directement à partir d'un jar.
Il y a deux façons d'accéder à une BDD en Java, en utilisant le
Driver JDBC ou le
DataSource JDBC.
On vous demande d'utiliser le
DataSource car la gestion des connections à la BD est automatique.
Dans le cas où vous utilisez JPA / Hibernate, il vous faut aussi ajouter une dépendence sur
Dialect
correspondant à votre base de donnees car chaque base de données parle un SQL un petit peu différent.
Attention, ces BDDs
embedded peuvent être utilisées aussi comme des BDDs classiques extérieurs
à l'application, ce n'est pas ce qui nous intéresse ici, on veut la version
embedded !
Et on ne veut pas que la base de donnée disparaisse quand on quitte l'application !
REST API documentation
Nous allons documenter l'API REST de votre
back-end, en utilisant le format Open API 3.
En utilisant l'application web
SwaggerUI (elle lit le format open API), vous allez pouvoir tester
votre API REST en dehors de votre application Web.
Note : il y a deux façons d'utiliser Open API, soit on l'utilise comme un générateur qui génère le squelette
de l'API, soit dans l'autre sens, on extrait les valeurs des classes Java. On va utiliser la seconde version,
comme cela, la documentation de l'API sera toujours à jour avec le code.
Pour vous aider, si vous ne respectez pas les indications de "sudden death" suivantes,
votre projet sera considéré comme mort et noté 0.
Pour la partie Java, le programme doit être écrit en utilisant correctement les différents concepts
vus lors du cours de Java Avancé (sous-typage, polymorphisme, pattern matching, lambdas, classes internes,
exceptions, types paramétrés, collections, entrées/sorties).
-
Une des technologies que votre projet utilise n'est pas celle requise pour votre binôme
-
Pour la partie concurrence, Faite attention à gérer correctement la concurrence,
spécifiquement, que l'on puisse intérroger votre LLM avec plusieurs requêtes en parallèle.
-
Vous avez la même API REST qu'un projet d'un autre binôme.
-
Vous utilisez le même prompt système avec le même LLM qu'un autre binôme.
-
Il ne doit pas y avoir de warnings lorsque l'on compile avec javac -Xlint:all.
-
Dans un module, les packages d'implantation ne doivent pas être exportés et
requires transitive doit être utilisé là où c'est nécessaire.
-
Il ne doit pas y avoir de raw types, de @SuppressWarning non justifié, de cast non justifié.
-
Le principe d'encapsulation et la programmation par contrat doivent être respectées.
-
Il ne doit pas y avoir de champs, méthodes ou classes protected.
-
Il ne doit pas y avoir d'instanceof/if...else sur des types là où il est possible
d'utiliser le polymorphisme ou le pattern matching.
-
Chaque interface devra être nécessaire.
Une interface possède 0 ou 1 méthode (sinon justifiée).
-
Aucune classe abstraite ne doit être publique ou utilisée comme un type.
-
Chaque méthode devra être appelée (pas de code mort).
-
Aucune méthode ne doit faire plus de 20 lignes sans une vraie justification.
-
Il est interdit d'utiliser des champs static typés par un objet (pas de variables globales),
seules les constantes (static final) de type primitif sont autorisées (et utiliser l'injection de dépendance SVP).
-
Le fichier POM.xml ne doit pas contenir de dépendances non listées dans ce document
où ayant une autre version que la version demandée (à part les dépendances de dépendances).