Quarkus a créé un véritable buzz dans l'écosystème Java d'entreprise en 2019. Comme tous les autres développeurs, j'étais curieux de cette nouvelle technologie et y voyais beaucoup de potentiel. Qu'est-ce que Quarkus exactement ? En quoi est-elle différente des autres technologies établies sur le marché ? Comment Quarkus peut-il m'aider ou aider mon organisation ? Découvrons-le.
Qu'est-ce que Quarkus ?
Le projet Quarkus s'est surnommé Supersonic Subatomic Java. Est-ce bien réel ? Qu'est-ce que ça veut dire ? Pour mieux expliquer la motivation derrière le projet Quarkus, nous devons examiner l'état actuel du développement logiciel.
Du local au cloud
L'ancienne façon de déployer des applications était d'utiliser du matériel physique. Avec l'achat d'une machine physique, nous avons payé d'avance les exigences matérielles. Nous avions déjà fait l'investissement, donc cela n'aurait pas d'importance si nous utilisions toutes les ressources de la machine ou juste une petite quantité. Dans la plupart des cas, nous ne nous en soucierions pas tant que nous pourrions exécuter l'application. Cependant, le Cloud change maintenant la façon dont nous développons et déployons les applications.
Dans le Cloud, nous payons exactement ce que nous utilisons. Nous sommes donc devenus plus exigeants avec notre utilisation du matériel. Si l'application prend 10 secondes pour démarrer, nous devons payer ces 10 secondes même si l'application n'est pas encore prête à être consommée par d'autres.
Java et le cloud
Vous souvenez-vous de la sortie de la première version Java ? Permettez-moi de vous rafraîchir la mémoire - c'était en 1996. Il n'y avait pas de Cloud à l'époque. En fait, il n'a vu le jour que plusieurs années plus tard. Java n'était définitivement pas adapté à ce nouveau paradigme et devait s'adapter. Mais comment pourrions-nous changer un paradigme après tant d'années liées à un matériel physique où les coûts importaient moins que dans le Cloud ?
Tout est question de runtime
La façon dont de nombreuses bibliothèques et frameworks Java ont évolué au fil des ans a été d'effectuer un ensemble d'améliorations à l'exécution. C'était un moyen pratique d'ajouter des fonctionnalités à votre code de manière sécurisée et déclarative. Avez-vous besoin d'une injection de dépendance ? Bien sûr ! Utilisez des annotations. Avez-vous besoin d'une transaction ? Bien sûr ! Utilisez une annotation. En fait, vous pouvez coder beaucoup de choses en utilisant ces annotations que le runtime choisira et gérera pour vous. Mais il y a toujours un hic. Le runtime nécessite une analyse du classpath et des classes pour les métadonnées. Il s'agit d'une opération coûteuse qui consomme du temps et de la mémoire.
Changement de paradigme avec Quarkus
Quarkus a relevé ce défi en déplaçant des opérations coûteuses telles que l'amélioration du bytecode, le chargement de classe dynamique, les proxys, etc. lors de la compilation. Le résultat est un environnement qui consomme moins de mémoire, moins de CPU et un démarrage plus rapide. C'est parfait pour le cas d'utilisation du Cloud, mais également utile pour d'autres cas d'utilisation. Tout le monde bénéficiera d'une consommation globale de ressources moindre, quel que soit l'environnement.
Peut-être que Quarkus n'est pas si nouveau
Avez-vous entendu parler ou utilisé des technologies telles que CDI, JAX-RS ou JPA ? Si c'est le cas, la pile Quarkus est composée de ces technologies qui existent depuis plusieurs années. Si vous savez comment développer avec ces technologies, vous saurez comment développer une application Quarkus.
Reconnaissez-vous le code suivant ?
@Path("books")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public class BookApi {
@Inject
BookRepository bookRepository;
@GET
@Path("/{id}")
Response get(@PathParam("id")Long id) {
return bookRepository.find(id)
.map(Response::ok)
.orElse(Response.status(NOT_FOUND))
.build();
}
}
Félicitations, vous avez votre première application Quarkus!
Le meilleurs des frameworks et standards
Le modèle de programmation Quarkus repose sur des standards éprouvées, qu'il s'agisse de standards officiels ou de standards de facto. À l'heure actuelle, Quarkus dispose d'un support de première catégorie pour des technologies telles que Hibernate, CDI, Eclipse MicroProfile, Kafka, Camel, Vert.x, Spring, Flyway, Kubernetes, Vault, pour n'en nommer que quelques-unes. Lorsque vous adopterez Quarkus, vous serez productif dès le premier jour car vous n'avez pas vraiment besoin d'apprendre de nouvelles technologies. Vous utilisez simplement ce qui existe depuis 10 ans.
Cherchez-vous à utiliser une bibliothèque qui n'est pas encore dans l'écosystème Quarkus ? Il y a de fortes chances que cela fonctionne "out of the box" sans configuration supplémentaire, à moins que vous ne vouliez l'exécuter en mode natif via GraalVM. Si vous voulez aller plus loin, vous pouvez facilement implémenter votre propre extension Quarkus pour prendre en charge une technologie particulière et enrichir l'écosystème Quarkus.
La configuration de Quarkus
Donc, vous vous demandez peut-être s'il y a quelque chose qui se cache sous le capot. En fait, oui. Vous devez utiliser un ensemble spécifique de dépendances dans votre projet fournies par Quarkus. Ne vous inquiétez pas, Quarkus prend en charge Maven et Gradle. Pour plus de commodité, vous pouvez générer un projet squelette dans la page de démarrage de Quarkus, et sélectionner les technologies que vous souhaitez utiliser. Importez-le simplement dans votre IDE préféré et vous êtes prêt à l'utiliser. Voici un exemple de projet Maven pour utiliser JAX-RS avec RESTEasy et JPA avec Hibernate :
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>code-with-quarkus</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus-plugin.version>1.3.0.Final</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>1.3.0.Final</quarkus.platform.version>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</project>
Vous avez peut-être remarqué que la plupart des dépendances commencent par le groupId io.quarkus et que ce ne sont pas les dépendances habituelles que vous pourriez trouver pour Hibernate, Resteasy ou JUnit.
Les dépendances de Quarkus
Maintenant, vous vous demandez peut-être pourquoi Quarkus fournit ses propres versions encapsulées de ces bibliothèques populaires. La raison est de fournir un pont entre la bibliothèque et Quarkus pour résoudre les dépendances d'exécution au moment de la compilation. C'est là que la magie de Quarkus se produit et fournit des projets avec des temps de démarrage rapides et des empreintes de mémoire plus petites.
Est-ce à dire que vous êtes contraint d'utiliser uniquement des bibliothèques spécifiques à Quarkus ? Absolument pas. Vous pouvez utiliser n'importe quelle bibliothèque de votre choix. Vous exécutez les applications Quarkus sur la JVM comme d'habitude, où vous n'avez pas de limitations.
GraalVM et les images natives
Peut-être avez-vous déjà entendu parler de ce projet appelé GraalVM par Oracle Labs ? En substance, GraalVM est une machine virtuelle universelle pour exécuter des applications dans plusieurs langages. L'une des fonctionnalités les plus intéressantes est la possibilité de créer votre application dans une image native et de l'exécuter encore plus rapidement ! En pratique, cela signifie que vous n'avez qu'un exécutable à exécuter avec toutes les dépendances requises de votre application résolues au moment de la compilation. Cela ne fonctionne pas dans la JVM - c'est un fichier binaire exécutable simple, mais inclut tous les composants nécessaires comme la gestion de la mémoire et la gestion des threads à partir d'une autre machine virtuelle, appelée Substrate VM pour exécuter votre application.
Pour plus de commodité, l'exemple de projet Maven a déjà la configuration requise pour créer votre projet comme natif. Vous devez avoir GraalVM dans votre système avec l'outil native-image installé. Suivez ces instructions sur la façon de procéder. Après cela, construisez simplement le projet comme n'importe quel autre projet Maven mais avec le profil natif : mvn verify -Pnative. Cela générera un exécutable binaire dans le dossier cible, que vous pouvez exécuter comme n'importe quel autre binaire, avec ./project-name-runner. Ce qui suit est un exemple de sortie du runner dans ma boîte :
[io.quarkus] (main) code-with-quarkus 1.0.0-SNAPSHOT (powered by Quarkus 1.3.0.Final) started in 0.023s. Listening on: http://0.0.0.0:8080
INFO [io.quarkus] (main) Profile prod activated.
[io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, narayana-jta, resteasy, resteasy-jsonb]
Avez-vous remarqué le temps de démarrage ? Seulement 0,023s. Oui, notre application n'a pas grand-chose, mais reste assez impressionnante. Même pour les applications réelles, vous verrez les temps de démarrage de l'ordre des millisecondes. Vous pouvez en savoir plus sur GraalVM sur leur site Web.
La productivité des développeurs
Nous avons vu que Quarkus pourrait aider votre entreprise à devenir Cloud Native. Impressionnant. Mais qu'en est-il du développeur ? Nous aimons tous les nouvelles choses brillantes, et nous sommes aussi super paresseux. Que fait Quarkus pour le développeur qui ne peut pas être fait avec d'autres technologies ?
Eh bien, que diriez-vous du rechargement à chaud qui fonctionne réellement sans utiliser d'outils externes ou d'astuces compliquées ? Oui c'est vrai. Après 25 ans, depuis la naissance de Java, nous avons maintenant un moyen fiable de changer notre code et de voir ces changements avec un simple rafraîchissement. Encore une fois, cela est accompli par la façon dont Quarkus fonctionne en interne. Tout n'est que du code, vous n'avez donc plus à vous soucier des choses qui ont rendu le rechargement à chaud difficile. C'est une opération banale.
Pour ce faire, vous devez exécuter Quarkus en mode développement. Exécutez simplement mvn quarkus:dev et vous êtes prêt à y aller. Quarkus va démarrer et vous êtes libre d'apporter les modifications à votre code et de les voir immédiatement. Par exemple, vous pouvez modifier les paramètres de vos endpoints REST, ajouter de nouvelles méthodes et modifier les chemins d'accès. Une fois que vous les invoquerez, ils seront mis à jour en fonction de vos modifications de code. À quel point cela est cool ?
Quarkus est-il prêt pour la production ?
Tout cela semble trop beau pour être vrai, mais Quakus est-il réellement prêt pour les environnements de production ? Oui, ça l'est.
De nombreuses entreprises adoptent déjà Quarkus comme environnement de développement/d'exécution. Quarkus a une cadence de publication très rapide (toutes les quelques semaines) et une forte communauté Open Source qui aide tous les développeurs de la communauté Java, qu'ils débutent avec Quarkus ou qu'ils soient un utilisateur avancé.
Découvrez cet exemple d'application que vous pouvez télécharger ou cloner. Vous pouvez également lire certaines des histoires d'adoption dans quelques articles de blog afin que vous puissiez avoir une meilleure idée de l'expérience utilisateur lors de l'utilisation de Quarkus.
Conclusion
Un an après son annonce officielle, Quarkus est déjà en version 1.3.1.Final. Beaucoup d'efforts sont déployés dans le projet pour aider les entreprises et les développeurs à écrire des applications qu'ils peuvent exécuter nativement dans le Cloud.
Nous ne savons pas jusqu'où Quarkus peut aller, mais une chose est sûre : Quarkus a secoué tout l'écosystème Java dans un espace dominé par Spring. Je pense que l'écosystème Java ne peut gagner qu'en ayant plusieurs offres qui peuvent se pousser mutuellement et innover pour rester compétitives.
Ressources
A propos de l'auteur
Roberto Cortez est un développeur Java passionné avec plus de 10 ans d'expérience. Il est impliqué dans la communauté Open Source pour aider d'autres personnes à diffuser leurs connaissances sur les technologies Java. Il est un conférencier régulier lors de conférences comme JavaOne, Devoxx, Devnexus, JFokus et autres. Il dirige le Coimbra JUG et a fondé la Conférence JNation au Portugal. Lorsqu'il ne travaille pas, il passe du temps avec des amis, joue à des jeux informatiques et passe du temps avec sa famille.