En règle générale, un ensemble de code (le code client) lie contre un autre (le code de l'API). La liaison Java est typiquement vérifiée entre .java et .class au moment de la compilation ou entre .Class & .Class au moment de l'exécution. Cependant, dans ce dernier cas, la vérification est aussi et lorsque de mauvaises références sont rencontrées (c'est-à-dire que c'est paresseux). P>
existe-t-il un moyen de forcer la vérification des liens tous les em> entre le code client et le code API à la fois avec code compilé? Le but serait de vérifier que le code client fonctionnera avec la version donnée de l'API - même s'il a été compilé contre un autre. P>
(Bien sûr, une solution serait de décompiler et de recompiler contre l'API, mais existe-t-il une méthode plus directe?) P>
6 Réponses :
Peut-être que vous pouvez exécuter des tests JUnit contre l'API spécifié par un pot dans le pavillon de classe, puis sortez simplement le pot pour différentes versions de l'API et exécutez à nouveau des tests. Vous seriez capable d'automatiser cela facilement. P>
Il est possible d'analyser le code des classes Java par réflexivité. Consultez le package Java.reflect . Certains outils d'analyse utilisent cette fonctionnalité pour obtenir des informations sur le code compilé. Le meilleur exemple est probablement Findbugs . P>
Cette API comme limite, et je ne pense pas que vous puissiez faire ce que vous voulez avec elle. Si une dépendance est appelée dans une méthode, l'API reflect peut trouver la méthode, ses paramètres, mais ne peut pas vous donner les fonctions dépendantes utilisées dans cette méthode. P>
Donc, je pense qu'un tel outil d'analyse n'existe pas en Java. P>
Une solution consiste à fournir une fois le code avec toutes ses dépendances. En développement, des outils de gestion de cycle de vie telles que Maven peuvent vous aider, gérer les dépendances de votre projet. P>
La vérification de la force des liens est difficile, en raison de la nature de la langue et de la mise en œuvre de la JVM. P>
Je pense que la justification de cette question est d'empêcher les erreurs de liaison au moment de l'exécution et l'intention de le faire est très valide. Toutefois, lorsque l'on examine la cause des erreurs de liaison, du point de vue de la JVM, il est plus ou moins difficile de verser une vérification de PEFFFORD sans impact sur la performance. P>
Les erreurs de liaison sont projetées au moment de l'exécution, lorsque le JVM exécute ByTecode correspondant au Instructions d'invocation de la méthode . Il est généralement à ce moment-là que la Le passage final du vérificateur ByTecode de JVM est lancé, ce qui pourrait entraîner des erreurs de liaison. Inutile de dire que cela coûte cher du point de vue des performances. P>
(c'est mon hypothèse que) la plupart des projets (y compris ceux commerciaux) évitent donc la vérification forcée, et s'appuient plutôt sur les systèmes de gestion de la construction et de la dépendance afin d'éviter la douleur. Plus de commentaires dans cette question à la question ; La réponse à choisir Osgi Framework pourrait aider. P>
La performance n'est pas nécessairement un problème majeur que le résultat peut être rappelé. En outre, dans certaines situations, la quantité de code ne sera pas nécessairement énorme.
D'accord, bien. Vous voudrez peut-être ensuite utiliser une bibliothèque d'ingénierie bytecode comme ASM (voir l'utilisation de CheckClassadapter) ou BCEL (qui a le vérificateur de justice dedans) pour effectuer une vérification si elles sont suffisantes ou les étendre si nécessaire. Je ne sais pas si Javassist a une caractéristique similaire.
Pour ce dont vous avez besoin, vous pouvez utiliser un outil comme Jarjardiff [1] et obtenir les différences entre la nouvelle version de l'ancienne version des pots API. Ensuite, la tâche est transformée pour vérifier que vous n'utilisez aucune des API incompatibles. Bien que non automatique, cette approche attire votre attention sur les changements et non seulement à la compatibilité binaire. p>
Si vous voulez simplement vérifier la compatibilité binaire, le plus facile est de recompiler le projet contre le nouveau pot. Un peu plus difficile (et beaucoup plus fragile) consiste à scanner le pavillon de classe et Invoquez chaque méthode de chaque classe, à la recherche d'exceptions de liaison. Notez que cette approche naïve ne testera pas tous les chemins possibles et offre peu d'avantages. P>
[1] http://depfind.sourceforge.net/tasks/jarjardiff.html < / a> p>
Prendre l'idée de cette question et Alfresco Wiki , vous pouvez essayer -xcomp code> pour lancer un test JVM et précompiler les classes Pour vérifier s'il y a une erreur de liaison. P>
Je recommanderais d'utiliser un outil de bytecode telle que ASM pour "visiter" le code et que votre visiteur remplace VisitMethodinsn . Utilisez ensuite la réflexion sur la classe propriétaire à la recherche d'une méthode avec le nom et la signature indiqués. Vous devrez également examiner le point de vue de l'instruction d'invocation - ce sera l'un des invoquesVirtual, InvokeInterface, invocale et invoquatique. Note pour faire attention à la distinction entre InvokeVirtual et InvokeInterface; Un appel à invoquirtual sera pas em> invoquer avec succès une méthode d'interface et un appel à invoquierface sera pas em> invoquer avec succès une méthode non définie sur une interface. P>