問題タブ [urlclassloader]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
2270 参照

java - 実行時にjarファイルを動的に追加するとNoClassDefFoundErrorが発生する

更新: この問題は、TestFramework.jar が JUnit に依存しており、(TestFramework) の読み込み時に junit jar が見つからないことが原因である可能性があると思います。私が正しければ、jar がロードされる順序を指定する方法が必要です。

JUnit TestCase の拡張であり、getTestData という名前のメソッドにテスト データを含む Java ソース ファイルをユーザーが指定できるようにするツールを作成しようとしています。次に、このツールは Java ファイルをコンパイルし、結果のクラス ファイルを「classes」ディレクトリに配置し、クラスをロードして getTestData メソッドにアクセスし、テスト データを表す XML ファイルを生成します。

明らかに、ユーザーがソース ファイルを指定できるようにすることで、コンパイル時にそのファイルのすべての依存関係がクラスパスに含まれていることも確認する必要があります。したがって、今のところ、テスト目的で使用しようとしている特定のファイルの依存関係をハードコーディングしました。ユーザーのファイルのコンパイルは現在機能していますが、結果のクラスをロードすると問題が発生します。繰り返しになりますが、クラスをロードするには、クラスが依存するすべてのファイルがクラスパス上にあることを確認する必要があることは明らかです。どういうわけか、クラスのロード中に必要なクラスが見つからず、NoClassDefFoundError が返されます。

以下は、「lib」ディレクトリ内の各 jar ファイルの URL を含む URLClassLoader を作成するために使用している方法です。ローダーはクラス変数であるため、すべてのメソッドで使用できますが、このメソッドでのみ初期化されることに注意してください。

コンパイルされたクラス ファイルを実際に検索してロードするコードを次に示します。最初のパラメータは内部を検索するディレクトリです。2 番目のパラメータは、ユーザーが XML ファイルを生成したいすべてのコンパイル済みクラス ファイルのリストです。

ユーザーが選択したソース ファイルのすべての依存関係が jar であるとは限らず、コンパイルされて "classes" ディレクトリに配置される他のソース ファイルもあることに注意してください。「classes」ディレクトリは、プロジェクト設定を介してランタイム クラスパスに含まれています (GUI の作成を簡素化するために Netbeans を使用しています)。ユーザーが「lib」ディレクトリにjarを動的に追加できるようにしたいので、プロジェクト設定でjarを指定しません。

出力とここで発生している問題については、コードを実行したときにコンソールに表示されるものです。

XmlDataGenerator.java の 299 行目は次の行です。IvrTest testCase = (IvrTest) Class.forName(fullClassName,true,loader).newInstance();

この時点で、次のような考えられるすべてのことを試したため、途方に暮れています。

  1. junit.jar をランタイム クラスパス (プロジェクト設定) に追加して、このエラーが確実に解消されるようにします。ただし、jar を動的にロードしたいので、これは問題の解決には役立ちません。
  2. ディレクトリ内のすべての jar をロードしようとする代わりに、junit.jar のみを指定します。これでも、上記と同じ失敗が発生します。
  3. プロジェクト構成から「クラス」ディレクトリを削除し、同じコードを使用してそれらのクラスを取り込みます。これはコンパイルされたソースを取り込むために機能しますが、jar の問題は修正されません。
  4. URL で絶対パスではなく相対パスを使用する。これは役に立ちません。
  5. jar のロードを試行する前後に System.out を追加します。結果は、UR​​LClassLoader の作成中に URL のリストを出力した場合と同じです。最初に作成したときとロードを試行した後では何も変わりません。

私が思いつく唯一のことは、使用しようとしている URLClassLoader が使用されていないということですが、なぜそれが起こるのかわかりません。どんな助けでも大歓迎です。御時間ありがとうございます。

0 投票する
0 に答える
1021 参照

java - URLClassLoader、「ホットスワップ」jar ファイル、および ClassFormatError - 奇妙な動作

5 月 25 日金曜日、グリニッジ標準時 16:00 頃にゼロから書き直しました

(コードがよりきれいになり、バグを再現できるようになり、質問がより明確になりました)

元の問題:ネット経由でクライアントからファイルを受け取り、URLClassLoader を介してローカルに保存された .jar ファイルからロードされる特定のクラスでそれらを処理するために必要なサーバー アプリを作成しています。ほとんどすべてが正常に動作しますが、これらの jar ファイルは (サーバー アプリを再起動せずに) ホット スワップされ、ホットフィックスが適用されます。ロードされると、ClassFormatError「切り捨てられたクラス」または「末尾の余分なバイト」に関するコメントとともにスローされます。それは当然のことですが、アプリケーション全体が不安定になり、その後奇妙な動作を始めます - これらのClassFormatError例外が発生し続けますURLClassLoader の新しいインスタンスを使用し、別のアプリ スレッドで発生したにもかかわらず、更新された同じ jar からクラスを再度ロードしようとすると。

アプリは Debian Squeeze 6.0.3/Java 1.4.2 で実行およびコンパイルされています。移行は私の力ではできません。

アプリの動作を模倣し、問題を大まかに説明する簡単なコードを次に示します。

1) メインアプリとクライアントごとのスレッドのクラス:

2) JarLoader - .jar からクラスをロードするためのラッパーで、Thread を拡張します。ここでは、特定のインターフェース a を実装するクラスをロードします。

3) IJarPlugin - プラグ可能な .jar のシンプルなインターフェース:

4) 実際のプラグイン:

バグを再現するには、同じクラス名を使用していくつかの異なる .jar をコンパイルする必要があります。唯一の違いは、"This is the Nth plugin:" の番号です。次に、メイン アプリケーションを起動し、ロードされた「1.jar」という名前のプラグイン ファイルを他の .jar にすばやく置き換え、ホットスワップを模倣して元に戻します。繰り返しClassFormatErrorますが、ある時点で予想されることですが、jar が完全にコピーされた場合 (および破損していない場合) にも発生し続け、そのファイルをロードしようとするクライアント スレッドを事実上強制終了します。このサイクルから抜け出す唯一の方法は、プラグインを別のものに置き換えることです。本当に奇妙に思えます。

実際の原因:

コードをさらに単純化し、clientThreadクラスを取り除き、インスタンス化してループJarLoader内で開始するだけで、すべてが明確になりました。がスローされると、スタック トレースが出力されるだけでなく、実際に JVM 全体がクラッシュしました (コード 1 で終了)。理由は今思うほど明白ではありません (少なくとも私にはそうではありませんでした): extends , not . したがって、キャッチされない例外/エラーのためにJVMは通過し、JVMは終了しますが、別の生成された(クライアント)スレッドからエラーを引き起こしたスレッドを生成したため、そのスレッドのみがクラッシュしました。Linux が Java スレッドを処理する方法が原因だと思いますが、よくわかりません。whilemainClassFormatErrorClassFormatErrorErrorExceptioncatch(Exception E)

(その場しのぎの)解決策:

キャッチされなかったエラーの原因が判明したので、「clientThread」内でキャッチしてみました。それはうまくいきました(スタックトレースの出力を削除して、自分のメッセージを出力しました)が、主な問題はまだ存在しClassFormatErrorていました.問題の.jarを置き換えるか削除するまで、. そこで、ある種のキャッシングが原因である可能性があると推測し、これを clientThreadtryブロックに追加して、URLClassLoader 参照の無効化とガベージ コレクションを強制しました。

驚くことに、うまくいくようです!エラーは 1 回だけ発生し、ファイル クラスは正常にロードされるようになりました。しかし、私は仮説を立てたばかりで、実際の原因を理解していないので、まだ心配しています.今は動作しますが、後ではるかに複雑なコード内で動作するという保証はありません.

では、Java をより深く理解している人は、本当の原因は何かを教えてくれますか、少なくとも方向性を示してくれますか? 既知のバグか、予想される動作かもしれませんが、すでに複雑すぎて自分で理解することはできません。私はまだ初心者です。そして、GC の強制に本当に頼ることができますか?

0 投票する
1 に答える
457 参照

java - URLClassLoader.addURL(URL)はMETA-INF /MANIFEST.MFを尊重しますか

にClass-Pathエントリを含むjarがある場合MANIFEST.MF。jarをに追加すると、エントリURLClassLoader内のjarも?に追加されますか?これを検出し、それぞれを(再帰的に)呼び出すために、追加するjarをイントロスペクトする必要がありますか?Class-PathclassloaderclassloaderaddURL

0 投票する
2 に答える
1510 参照

java - JavaJAR保護

Javaアプリをコーディングしましたが、オンラインで配布する予定です。各リリースは、私が作成した秘密のシリアルキーでロックされます。

逆コンパイラなどからjarファイルを保護する必要があります。これまでに行ったことは次のとおりです。

  1. ユーザーが自分のシリアルキーをフォームに入力します
  2. シリアルは、phpスクリプトを介して開発サーバーに送信されます
  3. スクリプトは、AES128で暗号化された新しいjarbinファイルを生成します
  4. 私の「ローダー」はjarファイルをバイトとしてダウンロードして復号化します。
  5. mainメソッドを呼び出します。
  6. ユーザーは好きなようにアプリを使用できます
  7. ユーザーがアプリを閉じる
  8. キャッシュがクリアされ、すべてがステップ1以前に戻ります。

手順1から3を実行しましたが、HTTPからバイトを取得し、それらを復号化してmainメソッドを呼び出すカスタムクラスローダーを作成できるかどうかを知る必要があります。ファイルは完全に暗号化されているため(PHPサーバーにbinとして保存されているため)、基本的なクラスローダーを使用できません。手順8について、コンピュータのメモリからコンテンツをアンロードすることはできますか?

0 投票する
2 に答える
4352 参照

java - ロックされたjarを使用したJavaクラスローダーのジレンマ

Java で classLoaders をいじっていて、奇妙なことに気付きました。classLoader が jar からクラスをロードする場合、classLoader の参照を解除しても、この jar は無期限にロックされます。

以下の例では、jar に HelloWorld というクラスが含まれています。私がしていることは、jar を動的に追加する classLoader を介して、jar に含まれるクラスをロードしようとすることです。に設定skipしてtrue呼び出さないClass.forName場合は jar を削除できますが、スキップせずにclassLoader( classLoader = null) を参照解除しても、JVM が終了するまで jar を削除できません。

何故ですか?

PS: 私は Java 6 を使用しており、コードはテスト目的で非常に冗長です。

0 投票する
1 に答える
307 参照

java - JarOutputStreamで作成されたjarのURLClassLoaderの問題

URLClassLoaderクラスは、以下にリストされたコードを使用してプログラムで作成されたjarからクラスをロードできませんが、jar cf%jarname%%sources%を使用して同じクラスでjarを作成すると、正常に機能します。jarcfJarOutputStreamを使用して作成されたjarに違いはありますか?

よろしく、ケシャフ

0 投票する
1 に答える
913 参照

java - OneJar と動的クラス ローディング

現在、アプリケーションでの OneJar の使用を調査していますが (さまざまな理由から)、アプリケーションは多数のカスタム を使用してURLClassloaderアプリケーション拡張機能をロードしています。

「OneJar」Jar としてバンドルされると、ClassNotFound例外が発生します。問題のクラスはバンドルされた Jar に存在し、親子関係を解決するためにクラスローダー メカニズムに依存しているだけです。

あれは。interfaceバンドルされた Jar (親のクラスローダー コンテキスト内にある必要があります) に格納されている共通があります。拡張機能はこれを実装しinterface(拡張機能を呼び出すことができるようにする)、親クラスローダーのリソース検出機能を使用する子クラスローダーの機能に依存します。

これを経験した人はいますか、それを解決する方法について何か光を当てていますか.

他の同様のメカニズムに興味があります(ライブラリのJarを単一のJarリソースにバンドルするため、すべてを解凍してJarを単一のファイルにする必要はありません)

0 投票する
1 に答える
1865 参照

java - tomcat でクラス ファイルをリロードする

実行時にクラスファイルを作成しています。

クラスローダーで既存のクラスファイルを更新したものに置き換えたいです。

これは、サーバーの再起動と再デプロイを回避するホット スワップ (JRebel など) に似ています。

コンテキストをリロードするための tomcat の context.xml アプローチを見つけました。ただし、本番環境の場合はあまり役に立ちません。

実行時に ClassLoader にクラスを登録できますか? 実行時にクラスをリロードする代替手段があるかどうかを提案してください。


次のコードを使用して、現在の classLoader を取得しています。

以下はロードクラスメソッドの実装です。

クラスをリロードするには、次のコードを使用しています。

クラスローダーの私の reload メソッドは

LoggingAspect の新しいインスタンスを作成するとリロードした後も、古いインスタンスが表示されます。提案してください。

それでも私は古いインスタンスを取得しています。

classloader が変更されたクラスをロードしない理由を教えてください。

0 投票する
0 に答える
105 参照

java - URLClassLoader : URL の設定方法

tomcat に app1 と app2 という 2 つのアプリケーションがあるとします。フォルダー構造は次のとおりです。 jar,test2.jar にクラスをロードする必要があるクラスが 1 つあります,これを達成する方法は?私は Java で知っています,リモート クラスをロードできる URLClassLoader があります,しかし、URL を設定する方法は? ありがとう

0 投票する
2 に答える
3151 参照

java - URLClassLoaderがクラスを見つけることができません

URLClassLoaderを使用して、jarアーカイブから特定のディレクトリのクラスをロードしたいと思います。

プロジェクト構成は以下のとおりです。

jarには次のマニフェストがあります。

私が現在行っていることは、次のように、内のすべてのファイルを反復処理し、/myClasses/その特定のクラス(すべて同じパッケージを持っている)をロードしようとしています。

しかし、ファイルが明らかに存在していても、私は常にjava.lang.ClassNotFoundException: de.myClasses.class1エラーが発生します。私は何が間違っているのですか?