質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.61%

クラスローダーでロードしたクラスに呼び出し元のシングルトンクラスを渡したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,575

mugichon

score 56

現在クラスローダーを使用し、クラスから別jarをロードし、実行しようと考えています。

クラスロードされたメソッドに大量のパラメータを渡したいため、呼び出し元クラスでシングルトンを作成し、
呼び出されるJAR内で取得、使用して結果を返すように実装したいと考えています。

シングルトン
public class Singleton {
  private static Singleton singleton= new Singleton();
  private static String TMP;
  public static Singleton getInstance(){
    return singleton;
  }
  public static String getTmp(){
    return TMP;
  }
  public static void setTmp(String s){
    TMP=s;
  }
}
呼び出し元
 Singleton sin;
 sin.getInstance();
 sin.setTmp("AAAA");
 File file = new File("ss.jar");
 URLClassLoader loader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()});
 Class<?> clazz = loader.loadClass("ss");
 method = clazz.getMethod("Run");
 Object obj = clazz.newInstance();
 method.invoke(obj);

呼び出し側
 public class ss(){
  Singleton singleton;
  singleton.getInstance();
  System.out.println(singleton.getTmp());
 }
結果
null

シングルトンは複数インスタンスを作成出来ないはずだと思いますが、
なぜクラスロードされた側ではシングルトンの値を取得できないのでしょうか?
また、取得する方法もあわせてご教示頂ければうれしいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

そもそも添付されたソースが一見して静的コンパイルすら通らないと思われるので何とも言い難いのですが...。
結論だけいえばクラスローダが異なればstatic変数の格納場所も異なるから、という話だと思いますが...。
※参考キーワードで探せばたくさんでで来ると思いますが、例えば
http://kagamihoge.hatenablog.com/entry/2016/01/14/145457
原文では
「By using separate ClassLoader you can also loads same class from multiple sources and they will be treated as different class in JVM. 」
で、若干脇道なんですが、上記SingletonクラスはSingletonになっていません。GoFのシングルトンパンターンだけがSingletonじゃないが、これでは"TMP"というstatic変数を格納したただの器です。
例えば

public class Singleton {
    private static final Singleton singleton= new Singleton();
    private String TMP;//<-staticでない
    public static Singleton getInstance(){
        return singleton;
    }
    public String getTmp(){
        return TMP;
    }
    public void setTmp(String s){
        TMP=s;
    }
}


staticに管理されるのはメンバでなくて、「ただ一つのインスタンスが指し示す先」の方です。
※直接staticにするのと何が違うのかという質問も良く受けますが、拡張性が違う。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/13 21:47

    ソースコードは覚えている限り写したので正確性がなかったかもしれません。。
    クラスローダーで呼び出した先にでは同一シングルトンを見ることはできないんですね。。
    残念ですが他に方法を考えて見ます。
    ご回答頂きありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る