問題タブ [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.
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();
この時点で、次のような考えられるすべてのことを試したため、途方に暮れています。
- junit.jar をランタイム クラスパス (プロジェクト設定) に追加して、このエラーが確実に解消されるようにします。ただし、jar を動的にロードしたいので、これは問題の解決には役立ちません。
- ディレクトリ内のすべての jar をロードしようとする代わりに、junit.jar のみを指定します。これでも、上記と同じ失敗が発生します。
- プロジェクト構成から「クラス」ディレクトリを削除し、同じコードを使用してそれらのクラスを取り込みます。これはコンパイルされたソースを取り込むために機能しますが、jar の問題は修正されません。
- URL で絶対パスではなく相対パスを使用する。これは役に立ちません。
- jar のロードを試行する前後に System.out を追加します。結果は、URLClassLoader の作成中に URL のリストを出力した場合と同じです。最初に作成したときとロードを試行した後では何も変わりません。
私が思いつく唯一のことは、使用しようとしている URLClassLoader が使用されていないということですが、なぜそれが起こるのかわかりません。どんな助けでも大歓迎です。御時間ありがとうございます。
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 スレッドを処理する方法が原因だと思いますが、よくわかりません。while
main
ClassFormatError
ClassFormatError
Error
Exception
catch(Exception E)
(その場しのぎの)解決策:
キャッチされなかったエラーの原因が判明したので、「clientThread」内でキャッチしてみました。それはうまくいきました(スタックトレースの出力を削除して、自分のメッセージを出力しました)が、主な問題はまだ存在しClassFormatError
ていました.問題の.jarを置き換えるか削除するまで、. そこで、ある種のキャッシングが原因である可能性があると推測し、これを clientThreadtry
ブロックに追加して、URLClassLoader 参照の無効化とガベージ コレクションを強制しました。
驚くことに、うまくいくようです!エラーは 1 回だけ発生し、ファイル クラスは正常にロードされるようになりました。しかし、私は仮説を立てたばかりで、実際の原因を理解していないので、まだ心配しています.今は動作しますが、後ではるかに複雑なコード内で動作するという保証はありません.
では、Java をより深く理解している人は、本当の原因は何かを教えてくれますか、少なくとも方向性を示してくれますか? 既知のバグか、予想される動作かもしれませんが、すでに複雑すぎて自分で理解することはできません。私はまだ初心者です。そして、GC の強制に本当に頼ることができますか?
java - URLClassLoader.addURL(URL)はMETA-INF /MANIFEST.MFを尊重しますか
にClass-Pathエントリを含むjarがある場合MANIFEST.MF
。jarをに追加すると、エントリURLClassLoader
内のjarも?に追加されますか?これを検出し、それぞれを(再帰的に)呼び出すために、追加するjarをイントロスペクトする必要がありますか?Class-Path
classloader
classloader
addURL
java - JavaJAR保護
Javaアプリをコーディングしましたが、オンラインで配布する予定です。各リリースは、私が作成した秘密のシリアルキーでロックされます。
逆コンパイラなどからjarファイルを保護する必要があります。これまでに行ったことは次のとおりです。
- ユーザーが自分のシリアルキーをフォームに入力します
- シリアルは、phpスクリプトを介して開発サーバーに送信されます
- スクリプトは、AES128で暗号化された新しいjarbinファイルを生成します
- 私の「ローダー」はjarファイルをバイトとしてダウンロードして復号化します。
- mainメソッドを呼び出します。
- ユーザーは好きなようにアプリを使用できます
- ユーザーがアプリを閉じる
- キャッシュがクリアされ、すべてがステップ1以前に戻ります。
手順1から3を実行しましたが、HTTPからバイトを取得し、それらを復号化してmainメソッドを呼び出すカスタムクラスローダーを作成できるかどうかを知る必要があります。ファイルは完全に暗号化されているため(PHPサーバーにbinとして保存されているため)、基本的なクラスローダーを使用できません。手順8について、コンピュータのメモリからコンテンツをアンロードすることはできますか?
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 を使用しており、コードはテスト目的で非常に冗長です。
java - JarOutputStreamで作成されたjarのURLClassLoaderの問題
URLClassLoaderクラスは、以下にリストされたコードを使用してプログラムで作成されたjarからクラスをロードできませんが、jar cf%jarname%%sources%を使用して同じクラスでjarを作成すると、正常に機能します。jarcfとJarOutputStreamを使用して作成されたjarに違いはありますか?
よろしく、ケシャフ
java - OneJar と動的クラス ローディング
現在、アプリケーションでの OneJar の使用を調査していますが (さまざまな理由から)、アプリケーションは多数のカスタム を使用してURLClassloader
アプリケーション拡張機能をロードしています。
「OneJar」Jar としてバンドルされると、ClassNotFound
例外が発生します。問題のクラスはバンドルされた Jar に存在し、親子関係を解決するためにクラスローダー メカニズムに依存しているだけです。
あれは。interface
バンドルされた Jar (親のクラスローダー コンテキスト内にある必要があります) に格納されている共通があります。拡張機能はこれを実装しinterface
(拡張機能を呼び出すことができるようにする)、親クラスローダーのリソース検出機能を使用する子クラスローダーの機能に依存します。
これを経験した人はいますか、それを解決する方法について何か光を当てていますか.
他の同様のメカニズムに興味があります(ライブラリのJarを単一のJarリソースにバンドルするため、すべてを解凍してJarを単一のファイルにする必要はありません)
java - tomcat でクラス ファイルをリロードする
実行時にクラスファイルを作成しています。
クラスローダーで既存のクラスファイルを更新したものに置き換えたいです。
これは、サーバーの再起動と再デプロイを回避するホット スワップ (JRebel など) に似ています。
コンテキストをリロードするための tomcat の context.xml アプローチを見つけました。ただし、本番環境の場合はあまり役に立ちません。
実行時に ClassLoader にクラスを登録できますか? 実行時にクラスをリロードする代替手段があるかどうかを提案してください。
次のコードを使用して、現在の classLoader を取得しています。
以下はロードクラスメソッドの実装です。
クラスをリロードするには、次のコードを使用しています。
クラスローダーの私の reload メソッドは
LoggingAspect の新しいインスタンスを作成するとリロードした後も、古いインスタンスが表示されます。提案してください。
それでも私は古いインスタンスを取得しています。
classloader が変更されたクラスをロードしない理由を教えてください。
java - URLClassLoader : URL の設定方法
tomcat に app1 と app2 という 2 つのアプリケーションがあるとします。フォルダー構造は次のとおりです。 jar,test2.jar にクラスをロードする必要があるクラスが 1 つあります,これを達成する方法は?私は Java で知っています,リモート クラスをロードできる URLClassLoader があります,しかし、URL を設定する方法は? ありがとう
java - URLClassLoaderがクラスを見つけることができません
URLClassLoaderを使用して、jarアーカイブから特定のディレクトリのクラスをロードしたいと思います。
プロジェクト構成は以下のとおりです。
jarには次のマニフェストがあります。
私が現在行っていることは、次のように、内のすべてのファイルを反復処理し、/myClasses/
その特定のクラス(すべて同じパッケージを持っている)をロードしようとしています。
しかし、ファイルが明らかに存在していても、私は常にjava.lang.ClassNotFoundException: de.myClasses.class1
エラーが発生します。私は何が間違っているのですか?