2010-08-11 5 views
9

J'ai ajouté un champ à Object classe, comme dans:Ajouter un champ à java.lang.Object

class Object { 
    ... 

    private Object _objInfo; 
} 

J'ai changé le code source de java.lang.Object et recompilé OpenJDK 6. Je reçois l'exception suivante lorsque la machine virtuelle bottes:

Error occurred during initialization of VM 
    java.lang.IllegalStateException 
    at java.lang.Throwable.initCause(Throwable.java:337) 
    at java.lang.ExceptionInInitializerError.<init>(ExceptionInInitializerError.java:79) 

Le même problème se produit lorsque je définis ma propre classe d'objets et préfixé à bOOTCLASSPATH, comme dans:

java -Xbootclasspath/p:<path to my Object class> 

Merci, Horatiu

+0

Pourquoi ne pas créer une classe pour mettre _objInfo? –

+2

Je ne pense pas que vous posez réellement une question n'importe où. –

+4

@justin, il est assez clair ce qu'il voudrait que nous l'aidions avec ... – jjnguy

Répondre

4

erreur est survenue pendant l'initialisation de VM java.lang.IllegalStateException à java.lang.Throwable.initCause (Throwable.java:337) à java.lang.ExceptionInInitializerError. (ExceptionInInitializerError.java:79)

La java.lang.IllegalStateException est levée si initCause() est appelé plus d'une fois. On dirait que votre modification d'Object provoque une exception et lorsque la JVM tente de créer un objet Exception (qui est une sous-classe de Object), il entre dans une boucle récursive et tente d'appeler initCause() plus d'une fois sur le même objet Exception.

Pourquoi voulez-vous modifier la définition de l'objet?

+1

Je dois garder certaines informations à l'exécution pour chaque objet utilisé comme un verrou. Pour cela, j'ai une carte de hachage globale qui mappe un ID obj retourné par System.identityHashCode() à certaines informations associées au verrou. Mais cette recherche est chère; Ce sera beaucoup plus rapide si j'avais un champ dans la classe Object qui peut pointer vers des informations arbitraires sur l'objet. –

+0

@HoratiuJula c'est exactement ce dont j'ai besoin pour mon profileur algorithmique, sauf que j'ai besoin de garder une trace de tous les objets profilés. Tout comme vous, j'ai commencé avec une carte indexée par 'System.identityHashCode()' seulement pour le trouver trop lent ... – vektor

1

Je suppose qu'il y a quelque chose dans l'implémentation de la JVM qui suppose la taille de l'objet. Vous l'avez fait plus grand pour que le code échoue.

Étant donné qu'il s'agit d'une erreur que les implémenteurs JVM n'ont jamais envisagée, la gestion des erreurs est interrompue.

La réponse: vous ne pouvez pas modifier l'objet sans faire beaucoup plus de travail.

3

Apparemment, il existe encore un certain nombre d'endroits dans le code natif où les décalages de champ sont câblés. Modifier certaines classes, telles que Thread, gâcher ceci. Si vous changez Object, vous les dérangez tous.

+0

Je sais, dans Dalvik VM (utilisé dans Android) j'ai eu le même problème ... Mais là, j'ai trouvé les offsets et les ai recalculés. Cependant, je ne sais pas où les offsets de champ pour Object, String, etc, sont codés en dur dans openjdk ... –

+1

@Horatiu Jula: il semble que la question que vous voulez vraiment répondre est ... "Quels changements ai-je besoin faire à l'openjdk 6 sources JVM si je prolonge l'empreinte mémoire de la classe Object? " Je vous préviens que la machine virtuelle openjdk est susceptible d'avoir été victime de quelques optimisations de performances très intenses qui vont faire les changements que vous devez faire pour supporter vos changements désirés à Object obtuse et généralisée. – vkraemer

+0

@Horatiu Jula: vous devrez peut-être aussi faire des mods pour javac. – vkraemer

9

Ne pas modifier Object. Ne modifiez rien dans java.lang. Je ne sais pas si c'est techniquement possible, mais c'est certainement une idée exceptionnellement mauvaise, et fondamentalement brise la plate-forme Java ("Q: Quel est le contrat de Object.equals()? A: Cela dépend quelles modifications personnalisées à la JVM faites-le ... ") - vous ne pourriez rien faire. Pensez à ce que vous faites - vous ajoutez cette classe (et le comportement possible) à tous les objets. ClassLoaders, chaînes, threads, InputStreams, Throwables, XMLGregorianCalendar, tout. Ce n'est certainement pas ce que vous vouliez.

Au lieu de cela, une autre approche serait d'ajouter vos modifications à une classe abstraite AppnameSuperObject et étendre ce pour les classes que vous vraiment voulez ajouter ce comportement à.


D'autre part, si vous ne voulez vraiment faire cela pour tous les objets pour une sorte de genre de travail enregistrement/profilage/etc, regardez en utilisant aspect-oriented programming à weave the extra fields onto the classes at runtime.

+0

Je l'ai essayé, ne fonctionne pas pour la classe d'objet ... –

+2

Ou, au lieu de donner des conférences, vous pouvez essayer de répondre à la question OP. Il y a cette idée radicale que si vous ne connaissez pas la réponse, vous ne devriez pas en poster une. Au lieu de cela, pensez à poser des questions de clarification dans les commentaires. –

+1

Comme Ted Neward l'a déjà décrit en 2001, bootclasspath existe en partie pour cette raison: pour pouvoir modifier les classes java. * (Http://www.tedneward.com/files/Papers/BootClasspath/BootClasspath. pdf) – Confusion

0

Vous feriez mieux de créer une classe X avec ce champ que vous souhaitez mettre en objet et de faire vos classes héritent de X.

Questions connexes