Ahhh Java... Je me souviens de mon tout premier code en Java. J'étais encore au lycée, je voulais apprendre à faire des sites web pour notre club d'anglais et j'avais entendu parlé de JavaScript. Alors j'ai demandé un bouquin à mes parents mais vu le prix des livres à l'époque j'avais fait une croix dessus... Puis à Noël...
J'ai reçu un libre qui s'appelait Total Java ! Et mes parents tout fiers à l'époque : "Le libraire nous a dit que tu pourrais faire des sites avec ça"... Oui avec des Applets Maman #Facepalm.
En réalité, j'ai très vite adoré Java et puis j'ai appris à le détester en migrant vers Kotlin. Le langage en lui-même n'est trop pas mal :
- Il gère la programmation par structures.
- Il gère la programmation orientée objets.
- Il gère la programmation fonctionnelle.
- Il gère la programmation par aspects.
- Il gère la programmation asynchrone.
- Il gère la programmation concurrentielle.
- Il gère programmation réactive.
- Il gère la programmation événementielle.
A présent je me rends compte de la lourdeur de sa syntaxe, que sa capacité à gérer autant de paradigmes différents font de lui un langage dont la syntaxe devient au final incohérente, que la rétro-compatibilité ascendante garantie n'a jamais permis à Java de trier le bon grain de l'ivraie pour ne se focaliser que sur le nouveau ; rétro-compatibilité depuis 1995 quand même !
@Warrior Du Dimanche si tu as des questions en Java demande, je tâcherai d'y répondre :-*. Mais quitte à bosser sur JVM, je te recommande Kotlin, bien plus élégant, bien plus expressif, bien mieux !
Excellente idée ! Merci à @Philou pour le lien.
Excellent, je cherchais un moteur Kotlin 2D sympa pour un kata un peu gros. C'est top !
Merci @Riduidel
Je suis bluffée ! Les filters des Stream sont toujours plus lents que les boucles classiques en Java.
Le seul moment où les boucles classiques ne sont pas les plus rapides, c'est dans le cas de figure où la taille des collections dépasse les 500 K éléments et que les Parallel Stream sont utilisées à la place des Stream (et que nous sommes sur une architecture multi-cœurs évidemment) ; sinon les Stream perdent à chaque fois.
Une lib Java rikiki de 153 Ko permet d'écrire des logs plus rapidement qu'avec LogBack ou Log4J2 et qui implémente les interfaces de SLF4J. #Nice
@Riduidel : la réponse à ta question est dans ce post (un peu long à lire désolée).
Un objet Iterable implique que l'on traite les données à partir d'un paradigme de programmation procédurale et impératif, c'est-à-dire ni objet, ni fonctionnel. Or les Optionals sont justement des éléments prévus spécialement pour penser et coder dans un style fonctionnel parmi les plus purs.
Vouloir que la classe Optional implémente Itérable, c'est un marqueur fort permettant d'identifier qu'une personne n'a pas encore appris et compris le paradigme fonctionnel où :
- Les instructions if/else/switch ont été remplacés par du pattern-matching.
- Les boucles for/while/do-while ont été remplacées par des appels récursifs.
- Les références ont été remplacées par des lambdas.
Enfin, le fait que Scala ait implémenté Iterable dans les Optionals est justement ce qui fait de Scala un mauvais langage fonctionnel à mon avis, car si c'est génial d'être multi-paradigme, c'est par contre très mal de mélanger les paradigmes dans les éléments constituants l'API du langage car cela créé un code extrêmement incohérent où il devient difficile de savoir comment s'exprimer ; mais c'est mon côté software craftswomanship qui parle #JavaDuchesses
De mon côté Kotlin est constaté dans deux banques et un géant de l'énergie (secteur Parisien) et nous sommes en train de le pousser comme langage par défaut sur le développements d'API qui doivent être utilisées sur des infrastructures ultra legacy (Weblogic + Java 7 #Pleure) pour les remplacer, car Kotlin permet justement de coder avec les features de 2021 et de transcompiler le bytecode vers de vielles JVM 6/7/8.
Rappelons que Java a mis 10 ans pour devenir Java et que quelques années plus tard il est à 1/8ème de son paroxysme, cf. cette Google Trend du 1er janvier 2004 au 7 mars 2021 montrant l'évolution de Java sur ces 17 dernières années.
En comparaison, Kotlin va seulement fêter sa 6ème année... Laissons-lui encore 4 ou 5 ans histoire de voir.
Un framework de test de mutation pour JRE, donc qui marche avec Kotlin et Java.
Très simple :
- Vous installez GraalVM en tant que JAVA_HOME.
- Vous installez native-image dans GraalVM via la commande
gu install native-image
. - Vous installer les GCC + build-essential :
sudo apt install gcc build-essential
- Vous ajoutez le plugin Maven dans votre projet.
Enjoy :D
Parser des fichiers CSV avec la lib OpenCSV en Java et en Kotlin.
Extrait du petit code qui va bien pour une lecture de trèèèès gros fichiers :
try (CSVReader reader = new CSVReader(new FileReader("file.csv"))) {
String[] lineInArray;
while ((lineInArray = reader.readNext()) != null) {
System.out.println(lineInArray[0] + lineInArray[1] + "etc...");
}
}
Cela fait pas mal d'années que je cherche un serveur web à embarquer dans mes applications à destination d'une JRE (Java Runtime Environment) et qui soit :
- Léger, quelques Ko maximum.
- Rapide à démarrer, quelques millisecondes maximum.
- Perfomant, qui encaisse une charge de plusieurs dizaines de milliers de requêtes par secondes sur mon core I5.
- Asynchrone, pour tirer partie du multithread.
- Compilable nativement, via Kotlin Native ou GraalVM.
- Ayant une syntaxe avec et surtout sans annotations, car la réflexion du code rend compliqué la compilation native.
- Libre, gratuit et interropérable.
- Présent dans le répo Maven Central.
- Modulaire, si j'ai besoin du routing alors je ne veux embarquer que les jars dédiés au routing.
Jooby répond à toutes ces conditions. Donc après avoir utilisé Glassfish (outch), Tomcat, Websphere (hur), Jonas (damned), Weblogic (hur again), Jetty, Sparkjava, Undertow, Javalin, Rapidoid et dernièrement Netty, je pense que je vais migrer vers Jooby qui en plus a de meilleures performances que les autres (d'un facteur 2 par rapport à son meilleur challenger, il est même au niveau des serveurs à destination du C++).
Dans la même veine que mon poste précédente et avec les mêmes remarques concernant la sécurité.
Tout est dans le titre.
Attention à l'extraction de fichiers dont le chemin dans l'archive sont des chemins absolus ! Si c'est root qui décompresse, il est alors possible d'écraser le /etc/profile
par exemple, voir modifier des démons gérés par systemctl
et compromettre le système.
Bref, toujours concaténer le répertoire de décompression en début de chemin du fichier.
Une page proposant tous les anciens JDK à télécharger.
Via Kalvn qui poste toujours des trucs qui me sont incroyablement utiles ! Thanks a lot :D
A lire pour plus tard.
Les nouveautés de Java 15 pour @Animal et @Doudou.
Merci à @Philou pour lien.
Pour @Lenny et @Kysofer qui doivent se servir de Netty.
EDIT 5: un cinquière tuto ici.
EDIT 4 : un quatrième tuto ici.
EDIT 3 : un troisième tuto ici.
EDIT 2 : un deuxième tuto ici.
EDIT : je viens de tomber sur ce tuto et quand je lis ce genre de code :
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
public class WebSocketHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof WebSocketFrame) {
System.out.println("This is a WebSocket frame");
System.out.println("Client Channel : " + ctx.channel());
if (msg instanceof BinaryWebSocketFrame) {
System.out.println("BinaryWebSocketFrame Received : ");
System.out.println(((BinaryWebSocketFrame) msg).content());
} else if (msg instanceof TextWebSocketFrame) {
System.out.println("TextWebSocketFrame Received : ");
ctx.channel().writeAndFlush(
new TextWebSocketFrame("Message recieved : " + ((TextWebSocketFrame) msg).text()));
System.out.println(((TextWebSocketFrame) msg).text());
} else if (msg instanceof PingWebSocketFrame) {
System.out.println("PingWebSocketFrame Received : ");
System.out.println(((PingWebSocketFrame) msg).content());
} else if (msg instanceof PongWebSocketFrame) {
System.out.println("PongWebSocketFrame Received : ");
System.out.println(((PongWebSocketFrame) msg).content());
} else if (msg instanceof CloseWebSocketFrame) {
System.out.println("CloseWebSocketFrame Received : ");
System.out.println("ReasonText :" + ((CloseWebSocketFrame) msg).reasonText());
System.out.println("StatusCode : " + ((CloseWebSocketFrame) msg).statusCode());
} else {
System.out.println("Unsupported WebSocketFrame");
}
}
}
}
J'ai juste envie de pleurer (et je vais vous expliquer pourquoi). La programmation orientée objets reposent sur trois principes :
- L'encapsulation.
- Le polymorphisme.
- L'héritage (mais il faut l'oublier car c'est un anti-pattern).
Le polymorphisme, c'est le fait qu'une classe fille puisse se faire passer pour sa classe mère. L'idée étant que l'on doit organiser notre code de telle sorte que nous puissions TOUJOURS utiliser les super-types (classe mère abstraite ou interface). Or dès que l'on doit ajouter des conditions du type truc instanceof Class
c'est que l'on passe à côté du principale intérêt du polymorphisme : ne jamais avoir besoin de dépendre des implémentations.
Soyons clair, dans un code orienté objet je n'ai jamais eu besoin d'écrire des instanceof
et de toute ma vie, ce n'a dû m'arriver qu'une ou deux fois et parce que je dépendais d'un code aussi vieux que Java lui-même !
Bref, si vous codez en Java et que vous avez besoin des implémentations, pis encore des instanceof
et des casts, alors c'est que vous pensez en procédural et non en objet. Et pour tout ceux qui souhaitent apprendre à penser en objet, je les renvoie aux formations de Kysofer (car il m'a promis une com' si vous y aller de ma part :D) et il y a la pré-collection automne de Sezane qui me fait grave de l’œil si vous voulez...
Tout est dit ! Et j'adore Kotlin c'est vous dire. Mais je préfère me tirer une balle que de faire du annotation-driven-development avec un java-procedural-spring-singleton-base programming.
Si je disais précédemment que la PF pure était un cancer, alors Spring et ce mode de programmation est un cancer metastasé !
Merci à @Philou qui me comprends et qui m'a offert ce lien.
Cela faisait quelques temps que je me demandais quel ORM choisir pour remplacer ActiveJDBC car ce dernier est très bien mais je souhaitais un framework qui accentue d'avantage l'OOP.
D'ailleurs ActiveJDBC avait remplacé depuis bientôt 5 ans maintenant Hibernate & OpenJPA chez moi, car eux-mêmes étaient beaucoup trop orientés procédurale (@Sweet clin d’œil à ce sujet) au point de rendre impossible de respecter le principe d'encapsulation et aussi parce que l'usage intensif de l'API réflexion par Hibernate ne permet pas la compilation en natif via GraalVM.
Bref, j'hésitais entre trois frameworks et je pense que je vais partir du Ktorm qui a une super doc, de bonnes performances et une façon très simple de requêter la base :
J'ai sorti Kuery car il n'est plus maintenu depuis trois ans et qu'il lui manque certaines fonctionnalités et j'ai aussi mis de côté Exposed car trop orienté fonctionnel et donc incitant à violer l'encapsulation à l'image d'Hibernate.
Bref Ktorm est dans le pipe.
Edit : voici un article complémentaire tiré de la documentation du projet OpenJDK sur le class-sharing de la JVM.
Précharger des classes pour démarrer une JVM plus vite. Je viens de faire le test avec Maven et ça a l'air de marcher un petit peu (mais le gain est négligeable lorsque l'on compare les temps de build à Gradle).
Toujours est-il que si cela peut apporter un peu de confort à certains, ou encore réduire les temps de démarrage des conteneurs, alors ça vaut le coup.
Merci à @Philou pour le lien.