7
votes

SOLUTION POUR LA CLASSECASTEXCEPTION DU PENDURE DE LA CLASSELLIER

J'ai deux chargeurs de classe qui charge la même classe. Donc, évidemment, ceux-ci ne peuvent pas se lanceront les uns aux autres. Mais je dois accéder à un objet créé dans l'autre chargeur de classe.

J'ai accès aux deux chargeurs de classe. Comment puis-je utiliser cet objet dans l'autre classe? Je n'ai pas besoin de jeter l'objet pour correspondre au chargeur de classe actuel.

Mais le problème est que le type d'objet retourné est objet . Donc, je dois jeter cet objet pour accéder à certaines méthodes. Comment puis je faire ça? Casting normal comme les causes suivantes ClasscastException, que je connais déjà. xxx

getMojo () retourne un objet de type mojo < / code> mais la méthode renvoie objet . Comment peut-on faire ça?

Faites-moi savoir si vous avez besoin d'autres informations.

J'ai lu toutes les théories à propos de la classement, mais aucun n'a spécifié une solution appropriée pour cela.


7 commentaires

Dans votre cas, que se passe-t-il si vous faites: objet o = descriptor.getmojo (); System.out.println (o.getclass); avec les deux chargeurs de classes différents?


La question la plus importante ici serait: qu'est-ce que vous en fait essayer d'atteindre ici? Est-ce un exercice académique ou un cas d'utilisation réel appui-t-il cette situation?


@ Famerer128 Il renvoie le même package de noms de classe.mojo. Je pensais que cela soit possible, effectuez ladite coulée via getclass () et #cast (objet O)?


@Sanjay T. Sharma absolument pas. Je travaille sur la correction d'un code existant.


@Ravana Avez-vous vu Cette question ?


@ Makerer128 Oui, la première suggestion de la réponse acceptée semble s'appliquer ici. Mais c'est vraiment bref et ne donne pas une solution finale appropriée


@Ravana, je n'ai pas l'expérience de répondre à cela, je vais donc le laisser à quelqu'un d'autre.


6 Réponses :


0
votes

Pourquoi vous avez 2 cloassloaders, qui charge la même classe? Cela pourrait être un problème programmatique. On dirait que vous mettez en cache un chargeur de classe quelque part et réutilisez-les de manière erronée. Si ce n'est pas le cas, essayez un chargeur multiclass.

Créer un chargeur multiclass comprenant plusieurs autres chargeurs de classe. Ce chargeur multiclass vous pouvez utiliser pour charger toutes les classes souhaitées. Mais vous devez créer ces multiclassloader au tout début et non lorsque les classes sont chargées. P>

protected Class findClass(String aName) throws ClassNotFoundException {
   for (Iterator iter = multiLoaders.iterator(); iter.hasNext();) {
      ClassLoader tmpLoader = (ClassLoader)iter.next();
      try {
         return tmpLoader.loadClass(aName);
      } catch (ClassNotFoundException e) {
      }
   }
   throw new ClassNotFoundException(aName);
}


4 commentaires

Malheureusement, je n'ai pas la capacité de changer les chargeuses de classe. J'ai accès aux deux, mais je ne peux pas créer quelque chose comme Multipleclassloader!


La méthode GetClass () renvoie-t-elle une classe contenant à la fois la classe et son chargeur de classe? Si oui, est-il un moyen de le faire en utilisant un mécanisme comme ça?


J'ai regardé cette solution. Je pourrais l'utiliser d'une autre manière. J'aimerais connaître un détail de plus. Dites, j'ai l'objet de la classe via votre méthode FindClass. Alors ce que je devrais faire? Comme je l'ai déjà dit, je dois jeter mon objet à cette classe retournée. Mojo = classe.cast (objet) me donne des erreurs de compilateur car elle pense que la CLASS # Cast renvoie un objet d'objet de type.


Vous pouvez implémenter votre code comme vous le faites normalement, avec un chargeur de classe unique. Le chargeur multiclassloader gère simplement le chargeur de classe MultiLpe, c'est tout.



0
votes

Le moyen le plus simple est d'utiliser la réflexion. Cela vous permet de dó tout ce que vous pouvez dó dans le code "normal".


2 commentaires

Je vois. Le code donné utilise la réflexion. Mais j'ai une connaissance très limitée sur la réflexion. Seriez-vous capable d'ajouter une solution simple à la réponse? Ça va être beaucoup utile!


Il n'y a pas de solution simple lors de l'utilisation de la réflexion. C'est assez fastidieux :(



8
votes

afaik, non, vous ne pouvez pas lancer un objet d'une classe chargée par un chargeur de classe dans une autre chargeur de classe.

  • Une solution serait de créer une chargeuse de classe "commune" qui charge les classes à utiliser par vos chargeurs de classe personnalisés. Donc, dans votre cas, vous auriez un nouveau chargeur de classe qui chargerait la classe donnée et vos chargeurs de classe personnalisés étendraient ce chargeur de classe.
  • Une autre solution serait de transmettre l'état "sérialisé" entre les deux chargeurs de classes. Serialize une instance à un tableau d'octets et reconstruisez l'objet dans l'autre chargeur de classe en désémarifiant le flux d'objets.

3 commentaires

Je ne veux pas le jeter d'un chargeur de classe à une autre. Mais c'est ce qui se passe ici quand je fais ladite casting. Comment puis-je faire cela, dans le même chargeur de classe? (Mojo) Descriptor.getmojo () ne fonctionne pas!


En effet, l'instance "Mojo" à l'intérieur du descripteur a été chargée par un chargeur de classe différent de celui que vous essayez de le récupérer. J'ai besoin de plus de contexte ici. Quel genre d'application est-ce? Application Web? Les threads multiples sont-ils impliqués ici?


C'est une application Java en cours d'exécution sur un seul fil. Utilisation de Classworlds 1.1 pour la classement.



1
votes

La réflexion n'est pas si mauvaise et est appropriée ici.
Est-ce un plugin maven, btw?

vous voudrez quelque chose comme: xxx

Je quitte beaucoup - en particulier la manipulation des exceptions - mais cela devrait vous amener au Javadoc dont vous avez besoin. C'est assez bon, mais lisez attentivement.

Si vous avez également deux classes de Mojo, la distribution se cassera et vous devrez faire plus de réflexion pour faire tout ce que vous devez faire avec le Mojo diabolique .


2 commentaires

C'est en effet un plugin maven. Je vais essayer cela et vous faire savoir comment ça se passe. Qu'est-ce que Javadoc vouliez-vous voulu?


La classe et la méthode pertinentes Javadoc.



1
votes

Je pense que la meilleure option pour stocker simplement le tableau des octets au lieu d'un objet. Tandis que déserliazing, obtenez un tableau d'octet en arrière et convertir en objet.

J'avais la même approche de numéro de numéro et d'octet fonctionnant. P>

ByteArrayInputStream bis = new ByteArrayInputStream(<<read byte[] where you stored earlier>>);
    ObjectInput in = null;

    try {
        in = new ObjectInputStream(bis);
        <Your Class >cachedRes = ( Your Class) in.readObject();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }


0 commentaires

0
votes

J'ai résolu cette question en chargeant la classe entièrement qualifiée à l'aide du chargeur de contexte parent de thread.

Par exemple, en utilisant abstractmojo ici. P>

       Thread
      .currentThread
      .getContextClassLoader
      .getParent
      .loadClass("org.apache.maven.plugin.AbstractMojo")


0 commentaires