Les vrais problème de Java

Le problème exposé dans ce sujet a été résolu.

Salut :)

J’entends très souvent dire que Java a une tonne de problème et j’aimerai bien savoir de quoi il s’agit concrètement (notamment les problèmes au niveau des génériques) Est-ce que les problèmes de Java sont plus sur d’ancienne version (un peu comme PHP) et que les gens ne se tiennent justes pas au courant ?

J’entends notamment souvent dire que les grosses boîtes migrent infra leurs javas EE vers Node (notamment par Christophe Porteneuve) (en raison d’une lenteur / poids)

J’aimerais vos avis là-dessus par curiosité et culture personnelle

La réponse courte:

Java comme tous langages à des défauts et des avantages.

La réponse longue:

Java est un langage vieillissant mais qui est très permissif (voir même trop). Il a été utilisé pour des backs ends mais à de gros problèmes de sécurité. Son principale avantage c’est d’être simple à aborder et d’être assez structuré. Au moment de sa popularisation il y avait une très forte demande le recrutement de profils pas expert était facilité par le langage. Beaucoup de désavantages comme la lenteur ou le coup en mémoire est souvent un reliquat de cette période. Le langage peut être utilisé pour faire du calcul scientifique http://www.hulis.free.fr/ ou même pour certains solveurs CSP https://github.com/chocoteam/choco-solver. Après un point qui me frustre au plus au point touche la tournure que prends le langage ces dernières années, il y a eu de lourds changements notamment sur la reflection et la gestion du class loader qui ont cassé beaucoup de choses.

Les +:

  • Simple
  • Structuré
  • De bonnes docs

Les -:

  • des choix discutables
  • une maitrise du langage vraiment pas simple surtout si tu veux optimiser le tout et assurer des performances correcte
  • les types natifs (int, char…)
  • beaucoup de préjugés sur le langage et de langage pourris
  • passoire niveau JVM (charger des programmes en mémoire, pouvoir lire pratiquement tout le contenu de la JVM permet certaines utilisation super cool comme la création d’api en quelques minutes ou optimisation sur la mémoire et vitesse mais le contre coup en terme de sécurité est pas top)
  • les nullpointerexception
+1 -0

C’est difficile de répondre à une telle question sans être plus spécificique. Tu dis que tu entends "très souvent" que Java a des tas de problèmes mais c’est très vague. Peut-être peux-tu demander aux personnes qui disent cela ce qu’elles veulent dire exactement.

Aussi, ça dépend de ce dont tu veux parler et de où tu voudrais utiliser Java. Application desktop ? Application Android ? Front-end ? Back-end ? Tu parles de problèmes de sécurité ou de problèmes liés au dévelopment ? Par exemple tu parles des génériques et j’imagine que tu parles du fait qu’ils ne sont pas réifiés. C’est effectivement un "problème" mais dans 99.9% des utilisations que tu en feras, ça ne te causera aucun problème et le choix d’implémentation peut être justifié par le choix d’être backward compatible.

Tu mentionnes que "les grosses boites migrent de Java EE1 vers Node". Franchement, j’ai de gros doutes que ca soit une vraie tendance mesurée. Java a été déclaré de nombreuses fois mort mais il est encore énormément utilisé, surtout dans des services back-end, et même dans des grosses boites.


  1. Java EE n’existe plus. C’est Jakarta EE maintenant.

De mon point de vue, ça dépend énormément de ce que tu veux en faire. En particulier, un usage classique serveur et un usage "programme graphique" vont te donner des expériences très différentes.

De mon expérience et pour un usage serveur, je dirais ceci :

Avantages

  • Langage fiable et éprouvé.
  • Énormément de ressources et de documentations de qualité.
  • Énormément de bibliothèques et frameworks de qualité dans tous les domaines.
  • Le langage évolue dans le bon sens, se modernise, devient plus lisible et agréable à utiliser.
  • Si tu sais un minimum ce que tu fais, la performance du langage (en fait de la JVM) n’est presque jamais un problème (tu auras des problèmes d’I/O disque, réseau ou BDD, ou des lenteurs algorithmiques avant).
  • Le compilateur JIT de la JVM HotSpot (la plus utilisée) uqi est très efficace.

Non-sujets dont tu entendras quand même parler

  • Des pans entiers du langage sont vieux et encore présents, mais sur un programme neuf tu peux les ignorer (vieilles API avant les collections, vieilles API de dates…)
  • La verbosité. Le vieux "Java pour entreprises" avec des Factory partout et des noms à rallonge n’est pas du tout obligatoire.
  • La question de la sécurité de la JVM mentionnée plus haut, dans un contexte serveur.
  • Les gens qui vont venir chouiner sur le sujet sans le connaître ("Haha Java c’est nul").

Inconvénients

  • Des reliquats antiques et erreurs de jeunesse que tu dois gérer (types natifs, subtilités sur les génerics…)
  • La gestion de la mémoire n’est pas simple, et ça n’est pas parce qu’il y a un garbage collector que tout est magique.
  • Le système de JVM à démarrer fait que la distribution ou l’exécution de petits programmes peut être très lourde pour le service rendu (même si des travaux vont dans ce sens).
  • Les surprises dues aux différences entre JVM qui ne sont pas censées exister.
  • L’usage "Desktop" qui pose des problèmes spécifiques, notamment de distribution et de sécurité (les deux derniers problèmes y sont beaucoup plus présents).

Quant au remplacement par Node, les fans de Node aiment bien en parler, mais j’ai l’impression que c’est assez rare, et le retour à Java existe aussi (notamment pour des raisons de performance, il y a des frameworks non bloquants en Java aussi maintenant).

L’usage "Desktop" qui pose des problèmes spécifiques, notamment de distribution et de sécurité (les deux derniers problèmes y sont beaucoup plus présents).

J’ai pas mal l’impression que le java client non sécurisé est bien moins existant aujourd’hui (plus d’applet, plus de java web start…)

J’ai pas mal l’impression que le java client non sécurisé est bien moins existant aujourd’hui (plus d’applet, plus de java web start…)

artragis

Exact. Les gros problèmes de sécurité de la JVM sont aujourd’hui des problèmes internes, qui se posent surtout si tu permets à ton programme d’exécuter du code qui ne lui appartient pas (plugin, mods de jeux…). Ce code tiers exécuté dans la JVM a eu, jusque très récemment, tous les droits sur tout le code accessible par la JVM, y compris celui d’accéder à des méthodes ou attributs normalement privés. Et inversement, tu peux très difficilement limiter les accès du code tiers.

Avec les dégâts qu’on imagine en cas de plugin/mod malveillant… Par exemple, un déconpilateur très connu pour Eclipse s’est rélévé envoyer plein de données privées à des serveurs en Chine.

PS : il reste le problème de la capacité de la JVM à changer dynamiquement des classes en provenance de… Ben en fait tu ne sais pas trop, selon le classpath. C’est même la source de la fameuse faille Log4j (qui permettait de charger des classes arbitraires selon une entrée utilisateur et ce à travers le réseau). Mais tant que tu maîtrises ce qui se passe dans ton classpath (pas sur desktop donc) et que tu ne laisse pas un chargement de classe se faire d’après une entrée non maîtrisée, le risque est très faible.

J’ai pas mal l’impression que le java client non sécurisé est bien moins existant aujourd’hui (plus d’applet, plus de java web start…)

A noter d’ailleurs que l’ensemble du package java.applet est officiellement déprécié depuis Java 17, et qu’il sera totalement supprimé dans une prochaine version. Après sa période de gloire au début des années 2000, il a suivi Flash ! Le dispositif de sécurité associé (SecurityManager & Co) va aussi prendre le même chemin.

Les gros problèmes de sécurité de la JVM sont aujourd’hui des problèmes internes, qui se posent surtout si tu permets à ton programme d’exécuter du code qui ne lui appartient pas

Ce problème-là existe dans tous les langages, ce n’est pas spécifique à Java. Dès le moment où on a un mécanisme de plugins dans son logiciel, de code de tiers chargeable dynamiquement, le risque existe. Malgré toutes les attentions du monde, mème le JavaScript client est fondamentalement dans le même cas vis-à-vis du navigateur web.

+0 -0

Ce problème-là existe dans tous les langages, ce n’est pas spécifique à Java. Dès le moment où on a un mécanisme de plugins dans son logiciel, de code de tiers chargeable dynamiquement, le risque existe. Malgré toutes les attentions du monde, mème le JavaScript client est fondamentalement dans le même cas vis-à-vis du navigateur web.

QuentinC

Ça m’amène à une question : est-ce qu’il y a des langages qui permettent d’exécuter du code tiers mais en limitant l’accès de ce code tiers à des API publiques, avec une impossibilité d’aller chercher des API privées ou de modifier des données privées ?

C’était théoriquement possible en Java (et les contournements les plus évidents à coup de réflexion ont été corrigés récemment sans trop de communication) ; mais pour les autres langages je ne sais pas.

À noter que je ne parle pas de la possibilité d’exécuter du code arbitraire (ça, tant que l’on a un système d’exécution de code tiers, ça vient avec, sauf à utiliser un langage spécial ultra limité). Je parle bien de l’intégrité de mon application : je pense au cas où l’application peut exécuter des plugins, ces plugins doivent pouvoir appeler mes API publiques comme ils veulent, et se perdre dans des boucles infinies s’ils sont mal programmés, mais ils ne doivent pas pouvoir modifier l’état interne de mon programme.

Ce problème-là existe dans tous les langages, ce n’est pas spécifique à Java. Dès le moment où on a un mécanisme de plugins dans son logiciel, de code de tiers chargeable dynamiquement, le risque existe. Malgré toutes les attentions du monde, mème le JavaScript client est fondamentalement dans le même cas vis-à-vis du navigateur web.

QuentinC

Ça m’amène à une question : est-ce qu’il y a des langages qui permettent d’exécuter du code tiers mais en limitant l’accès de ce code tiers à des API publiques, avec une impossibilité d’aller chercher des API privées ou de modifier des données privées ?

SpaceFox

Je dirais que pour faire ça tu as besoin ou bien d’établir un protocole de remote code qui encode les appels utilisés pour être sûr qu’il n’y ait pas d’autres appels que tes API publics.

Sinon faut que tu l’exécutes dans une sandbox où uniquement les appels aux API que tu choisis sont accessibles.

Dans les deux cas je pense pas qu’un langage l’implémente tel quel, sauf à essayer de le faire à coup de namespaces ? (la seule option que je vois)

Lorsqu’on utilise un langage de script au sein d’une application, on peut limiter celle-ci à une API: on expose que les fonctions que le langage pourra utiliser. Si on veut un accès restreint au disque, on remplace l’API filesystem par une fonction de notre cru. Certains langages comme lua sont faits pour, d’autres moins. On pourrait le faire avec n’importe quel langage qui utilise une VM ou un interpréteur, mais il faut que la fonctionnalité existe.

Pour des plugins sous forme de bibliothèque, on peut toujours exposer une API pour notre application, mais on ne peut pas limiter les possibilités du langage qui est de toute manière indépendant. On peut même corrompre la mémoire (de manière volontaire ou non).

Pour ce dernier cas, on peut faire de l’isolation de processus (un plugin dans un processus) et y mettre un certain nombre de permission, comme une restriction sur le filesystem. L’isolation a néanmoins un coût.

L’autre possibilité est de compiler le plugin dans un langage isolable. C’est ce qu’expérimente Mozilla sur Firefox avec du code C ou C++ compilé en wasm qui offre un accès restreint et contrôlé au monde extérieur. Ce qui permet de revenir au premier cas avec un langage de script / VM.

Ça m’amène à une question : est-ce qu’il y a des langages qui permettent d’exécuter du code tiers mais en limitant l’accès de ce code tiers à des API publiques, avec une impossibilité d’aller chercher des API privées ou de modifier des données privées ?

A un moment donné, je m’étais renseigné pour embarquer Python dans un programme C++, et la conclusion a été que Python est très mauvais à ça par exemple. ON peut trouver des codes sur le net qui arrivent à récupérer le module sys ou appeler la fonction open, quand bien même le programme hôte a pensé à bloquer import sys et redéfini open = None.

Si on veut avoir le maximum de sécurité, on est effectivement obligé d’utiliser des langages de script qui ont été spécialement pensés pour ça, comme lua ou AngelScript. ET même avec lua il faut faire très gaffe. Par exemple l’implémentation LuaJIT offre un module ffi qu’il ne faut pas oublier de bloquer.

Bref, c’est très très dur de blinder son programme hôte contre des plugins potentiellement malveillants.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte