0

クロスアプリケーション/アプレットJavaアクセシビリティサービスの観点から、どのようにパッケージにリンクしますが、実行時にパッケージの存在/可用性(すでにロードされている)に基づいてオプションでのみアクションを実行しますか?

ここで私が興味を持っているのは、階級のアイデンティティの危機を解決する方法だと思いますただし、オブジェクトを共有する2つのアプリ間で問題が発生するのではなく、クラスローダーの上位レベルでロードされるサービスである必要があります。リフレクションが進むべき道のようですが、この方法で派生クラスを実装する方法や方法がわかりません。特定のオプションクラスから派生した特定のリスナーを追加する必要があります。アプレットクラスローダーを使用してリスナーをロードできますが、内部はまだ失敗します。JInternalFrameListenerを追加したいが、Swingが使用可能であるとは限らなかったとします。リフレクションを使用すると、リスナーを追加するメソッドを見つけることができますが、関連するクラスが見つからない場合に、フレームリスナーを作成して機能させるにはどうすればよいですか。基本クラスローダーで見つからないためです。クラスを確実にロードできるように、スレッドを作成し、swingを認識しているクラスローダーに対してsetContextClassLoaderを使用する必要がありますか?既存のスレッドにクラスローダーを設定しようとしても、うまくいかなかったようです。

問題の以前の説明 申し訳ありませんが、何を尋ねるか、これを明確にする方法がよくわからないので、少し混乱します。

クラスが別のクラスの機能を使用しているが、他のクラスが常に利用できるとは限らないとします。たとえば、これがJNLPアプリの場合は、JNLPからWebサイトを検索します。

ある段階で、JNLPに対してコンパイルするだけでは、JNLPが利用可能でない限りクラスがロードされないことを意味すると思ったので、このオプションのセクションを識別するために、単にそれをラップしtry{} catch( NoClassDefFoundError )ました。

後で何かが変更され(おそらくjdkまたは??私は思い出せません)、私も。を使用する必要があるように見えましたtry{} catch( ClassNotFoundException )

今、私はこのアイデアを他のオプション機能に拡張したかったのですが、一貫して機能していないようです。

JRE1.3で実行するのと同じjarとクラスを使用してJRE1.6ランタイムでより高度な機能を追加したいとします。または、特定のGUIツールキットでいくつかのコントロールを処理したいとします。 SWTまたはoracle.formsのように使用できます。

これをより確実に行う方法はありますか?例外を発生させ、それをキャッチして常に無視するのは間違っているようです。

現在の問題は、oracle.formsに対してコンパイルできることですが、oracle.formsパッケージのオブジェクトが作成されていても、extにインストールされているアクセシビリティコンポーネントがoracle.formsクラスにアクセスできません。テストするためにfrmall.jarをextディレクトリにスローすると、同じパッケージのバージョンが異なるために、アクセシビリティコンポーネントが機能し、ロット全体が不安定になります。

クラスローダーが適切ではないという問題に巻き込まれているようです(??)。どうすれば正しいものを見つけることができますか?

編集:これまでの答えはちょっと面白いですが、私がなりたい場所に私を完全に導くことはできません。

GUIコンポーネントの場合、私は現在、次のようなファクトリの形式でコンパイルしています...

import oracle.forms.ui.*;
import java.awt.*;
static public IComponentNode newNode( INode parent, Component component ) {
  System.out.println( component.getClass().toString() );
  try{
  if( component instanceof FormDesktopContainer )
     ... does stuff here like return new FormDesktopNode( parent, (FormDesktopContainer) component )
  } catch ( NoClassDefFoundError a ) {
    System.out.println( a.getMessage() ); 
  }

ここで、出力してからclass oracle.forms.ui.FormDesktopContainer、NoClassDefFoundを使用したinstanceof呼び出しで例外をスローし、出力します。oracle/forms/ui/FormDesktopContainer

では、どうすればクラスのインスタンスを作成できるのに、それを見つけることができないのでしょうか。

4

4 に答える 4

2

これはどう?厄介ですが、うまくいくはずです:

public boolean exists(String className){

  try {
      Class.forName(className);
      return true;
      }
  catch (ClassNotFoundException){
      return false;
  }
}
于 2009-04-15T15:23:59.463 に答える
1

電話でクラスの空き状況を確認できます

ClassLoader.getSystemClassLoader().loadClass("my.package.MyClass")

ClassNotFoundExceptionがスローされた場合、それは使用できません。Classオブジェクトを取得すると、そうなります。次に、クラスが利用可能かどうかに基づいて動作を選択できます。

于 2009-04-15T15:23:31.897 に答える
0

コードの大部分を最小ターゲットに対してコンパイルすることをお勧めします。特定のオプションのライブラリを使用するコードを明確に分離しますが、コードの大部分に依存します。オプションのライブラリを使用するコードを1回動的にロードします。メインクラスは、静的イニシャライザーに必要なライブラリ/バージョンが存在するかどうかをチェックする何かを実行する必要があります。

JNLPの場合、JNLPメインクラスはJNLP依存コードを静的にロードします。

(通常リンクされているコードからクラスローディング関連の例外をキャッチしようとするのは信頼できないことに注意してください。)

于 2009-04-15T15:31:33.017 に答える
0

getSystemClassローダーは、特定のウィンドウがどのアプレットにあるかに基づいて対話する可能性のある複数のクラスローダーがあるため、この目的には役立ちませんでした。より基本的なクラスローダーでロードされるアクセシビリティコンポーネントは、アプレット固有のクラスを認識できません。

オブジェクトリフレクションと対話することは仕事をしますが、それは維持するために非常に多くを追加します。

// statically linking would be
return component.getText();

// dynamically is
try {
  return (String)component.getClass().getMethod("getText", new Class [] {}).invoke(component, new Object [] {});
} catch (Throwable e) {
  e.printStackTrace();
}

トリッキーな点は、直接アクセスできないインターフェイスから派生したクラスを作成することです。プロキシサービスを使用すると、これを実現でき、プロキシサービスにアプレット固有のクラスローダーとインターフェイスの動的にロードされるクラスが提供されます。

public void addListener(Container parent) {
  if (parent == null) { return; }
  if ("oracle.forms".equals(parent.getClass().getName())) {
    // Using the class loader of the provided object in the applet
    // get the "class" of the interface you want to implement
    Class desktopListenerClass = Class.forName( "oracle.DesktopListener"
         , true, parent.getClass().getClassLoader());

    // Ask the proxy to create an instance of the class, 
    // providing your implementation through the InvocationHandler::invoke
    Object desktopListener = Proxy.newProxyInstance(
         parent.getClass().getClassLoader()
         , new Class[] { desktopListenerClass }, new InvocationHandler() {

      public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable {
        if ("functionName".equals(method.getName())) {
          // do stuff
        }
        return null;
      }
    });

    // do something with your new object
    Method addDesktopListener = parent.getClass().getMethod("");
    addDesktopListener.invoke(parent, desktopListener);
  }
}

一般的な方法を示すために例を切り詰めた

于 2009-09-30T02:15:07.703 に答える