7
votes

Comment émettre des versions de fichier de classe plus récentes avec SCALA (50.0 / 51.0)?

Je veux tester le nouveau vérificateur de vérification de type-vérification de type avec des classes créées par scalac .

scalac produit actuellement des fichiers de classe 49.0, mais le nouveau vérificateur de contrôle de type n'est obligatoire que depuis la version 51.0.

J'ai essayé de "préversifier" les classes avec PROGUARD (qui les convertit en effet vers la version 50.0), mais je ne sais pas si le nouveau vérificateur est tombé automatiquement à l'ancienne vérificateur de type-Cerificateur.

Comment puis-je convertir des fichiers de classe en version 51.0 (ou comment puis-je savoir quel vérificateur est utilisé lors du chargement des fichiers de classe 50.0 de la version)?


0 commentaires

5 Réponses :


1
votes

Je ne suis pas sûr, mais je pense que le format Bytecode n'a jamais été profondément changé et qu'il est probablement toujours compatible avec la rétroaction. (Si vous savez quelque chose à propos de ByTecode, rappelez-vous que les longs et les doubles sur la piscine constante et la pile d'opérande, qui ont été conçus un peu follement. Il n'a pas été modifié, l'a donc?) Ainsi, le changement majeur / mineur va probablement fonctionner.

Comment faire? Il y a deux manières:

  • Utilisez l'éditeur Hexa et modifiez-le manuellement. Cela devrait être vraiment simple si vous connaissez la position des octets. Il y a la [spécification de bytecode] [1], qui dit que vous devez sauter les quatre premiers octets et vous verrez deux octets de version mineure et deux octets de la version principale (dans cet ordre).
  • Utilisez une bibliothèque. J'ai une certaine expérience avec BCEc. Il ne semble pas être la meilleure bibliothèque conçue que j'ai jamais vue, mais cela devrait être assez bon pour votre cas. J'ai vu des méthodes SetMinor et Setmajor dans une classe (regardez Classgen et le JavaClass «presque immuable»).

    [1] http: //java.sun .Com / Docs / Books / JVMS / SECOND_EDITION / HTML / ClassFile.doc.html


2 commentaires

Non, cela ne fonctionnera pas. 51.0 introduit un attribut obligatoire StackMap, utilisé avec le vérificateur de vérification de type. Changer la version ne l'ajoutera pas.


Hmm, qui est interrestant. J'ai pensé que ce n'est pas obligatoire. (Je ne parle pas d'un concept similaire dans J2ME.) Cependant, je ne comprends pas l'action "avant de préversifier" que vous avez fait. Si c'était le J2Me Preverify, il ne serait pas imho convertir le fichier de classe à une telle nouvelle version. Si ce serait le concept plus récent, il faudrait le convertir en 51,0 et non 50.0. À propos, vous pouvez également vérifier l'ASM Bibliothèque / Outils. Je l'ai utilisé pour certaines vérifications de bytecode lors du débogage et il a été capable de déduire des types de stack, de sorte que la génération de piles peut être construite sur cet IMHO simplement.



1
votes

J'utiliserais ASM pour analyser le bytecode. Je sais que Scala (et Clojure) utilise ASM en interne, donc les efforts déployés pour apprendre ne seront pas gaspillés. Vous pouvez probablement jeter ensemble un classReader et an EticleVisitor qui remplace la méthode de visite que fournit des informations d'en-tête assez rapidement.


2 commentaires

Scala n'utilise pas ASM en interne.


J'avais même pensé le vérifier en ligne avant de l'avoir dit. Apparemment seulement le scala Plugin Eclipse . Mes appologies pour l'erreur.



0
votes

Je sais que cela peut être évident, mais je ne suis pas sûr après avoir lu votre question, je vais donc demander:

Utilisez-vous une bêta-construction? Comme dans l'un des bâtiments nocturnes? Ou voulez-vous modifier la version actuelle?

EDIT: OK, il y a quelque chose que je ne comprends pas ici. Je viens d'essayer les constructions nocturnes et oui, ils sont la version 49.0. Mais autant que je sache, cela est défini par le compilateur.

Vous essayez de changer la version pour accéder à une nouvelle fonctionnalité de fantaisie. Mais cela n'a pas de sens pour moi. Si le compilateur publie la version 49.0, vous le modifiez à une version plus récente (50,0, 51,0 ou 70,0 pour ce qui compte) ne devrait avoir aucun impact. Pour autant que je sache la version consiste à assurer une compatibilité, ce qui signifie que vous n'exécuterez pas de classe plus récente avec un ancien VM qui ne prendra pas en charge votre langue.

Donc, dans votre cas, l'ajout d'une nouvelle version signifie que, probablement, la VM actuelle ne voudra pas exécuter votre code. Et même si cela ne contient probablement pas les fonctionnalités que vous mentionnez, si cette fonctionnalité est uniquement dans la version 51.0 que votre compilateur actuel / VM ne prend pas en charge.

Je veux dire, peut-être que ce que vous essayez de faire est complètement normal et que je ne le sais pas et je montre mon ignorance dans ce domaine :), mais je pense qu'il manque quelque chose qui manque là.


1 commentaires

J'utilise le coffre actuel 2.9.



0
votes

Je suppose que l'une des choses les plus faciles à faire serait d'utiliser un décompiler Java (voir Jadclipse pour un plug-in Eclipse), puis recompilez la source à la version dont vous avez besoin.


1 commentaires

Je ne pense pas que cela survivra à la rondette entre Scala Source -> Bytecode -> Java Source -> Bytecode. Tout pas à Scala ne peut être traduit en Java.



2
votes

Il semble que FJBG (la bibliothèque NSC utilise pour générer ByTecode) a vu certains effort à soutenir StackMap Mais je n'ai aucune idée à quel point c'est long.

Si vous demandez sur Scala-Internals, Stéphane Michelou pourrait apparaître. Il est le gars qui a été Travailler sur celui-ci .


1 commentaires

Merci! Votre réponse était assez intéressante et utile.