メモリjar /クラスファイルの実行

jar java memory
メモリjar /クラスファイルの実行

HTTPサーバーからファイル/ストリームとして利用可能な特定の場所にjarファイル(たとえばapp.jar)があります。 問題は、app.jar自体が頻繁に更新されるjarファイルであり、サーバーで定期的に更新されることです。 別のjarファイル(load.jarなど)があり、これはどのユーザーでも簡単にダウンロードできます。 実行時に、ユーザーはload.jarを実行します。これは、app.jarをメモリに保持したまま(ディスクへのキャッシュなし)別のプロセスでapp.jarをロードし、app.jarを実行して終了します(ロードします)。 jar)。 行うことは可能ですか? 任意の助けは大歓迎です。 前もって感謝します。 よろしく、KT

  • – – – – – – – – – – – – -更新。

Hi,

返信いただきありがとうございます。 しかし、私は完全な絵を与えていないと思います。 シナリオを示す画像* _http://www.freeimagehosting.net/image.php?1ec6fd4363.jpg [リンクテキスト] _ *が添付されています。 4つのjar(実際の一般的なエグゼキューター)は中央サーバーでホストされます。 これらは頻繁に更新されます(おそらく、最初は1日に3〜4回、最終的には1日に1回)。 メンバーの1つのローカルサーバーがホストされ、初期化されます。 ローカルサーバー上のランチャーは、4つのバイナリをすべてダウンロードし、メモリに保持します-ディスクへのキャッシュはありません。 これらのjarファイルは自己完結型であり、「ローカルサーバー」上のライブラリに依存しません。実際には、「ローカルサーバー」からjarを呼び出します。 「クライアント」jarは最終的に「ローカルサーバー」でホストされ、「ローカルサーバー」によってwebappを介してオンデマンドでクライアントに転送されます。 また、Launcherは、ダウンロードしたメインjarを別のJVMのサーバーから呼び出すことで終了する必要があります。

よろしく、KT

  4  4


ベストアンサー

OK. szegedi記事へのリンクを以前の回答(正直なところ)に入れる前に、URLを処理できるjar-launcherのプロトタイプを作成しました。 著者が言ったように、それは難しくはなく、おそらく完全ではありません。 以下に添付。 これはあなたが必要とするものの1/3だと思います。 あなたのユーザーは次のように言います:

java -jar load.jar http:// localhost:8080 / app.jar

load.jarには2つの役割があります。(1)メインクラスとしてJarLauncherを呼び出す(以下)(2)localhostポートでapp.jarを提供する(JarLauncherを呼び出す前)。 したがって、load.jarは引数を読み取って、実行するアプリを判断します。

最後に(ハードビット):URLClassLoaderが一時ディスクにヒットしないようにする必要があります。 セゲディの記事が言ったように、それは簡単ではありません。 または、URL接続からバイトストリームとしてURLをメモリにロードし、JarInputStreamとしてデコードし、loadClass /そのメモリ内ストリームからのfindResource。

あなたはかなり多くの仕事を前にしています。 がんばろう。

ライセンステキストのサイズはおApびしますが、私を責めない限り(BSD)、コードを使用して好きなことを行うことができます。

-サイモン。

” ” ‘

/*
 * One-JAR(TM) (http://www.simontuffs.com/one-jar).  Copyright (c) 2004-2010,
 * P. Simon Tuffs ([email protected]).   All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of P. Simon Tuffs, nor the names of any contributors,
 * nor the name One-JAR may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Including this file inside the built One-JAR file conforms with these terms.
 */

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.jar.JarInputStream;

/**
 * Programmatic equivalent of what happens when you say "java -jar ".
 * A better solution to debugging/running Jar files inside an IDE.
 * @author simon
 *
 */
public class JarLauncher {

    public static URL getURL(String string) throws MalformedURLException {
        try {
            return new URL(string);
        } catch (MalformedURLException x) {
            return new URL("file:" + string);
        }
    }

    public static void main(String args[]) throws Exception {
        if (args.length < 1) {
            System.out.println("Usage: java [-Dkey=value...] JarLauncher ");
            System.exit(1);
        }
        String jar = args[0];
        args = Arrays.copyOfRange(args, 1, args.length);
        List urls = new ArrayList();
        // Main jar on the URL path.
        // Dig out the main class.
        urls.add(getURL(jar));
        URL jarurl = urls.get(0);
        JarInputStream jis = new JarInputStream(jarurl.openStream());
        String main = jis.getManifest().getMainAttributes().getValue("Main-Class");
        // OK to split on space, because embedded space is %20
        String classpaths[] = jis.getManifest().getMainAttributes().getValue("Class-Path").split(" ");
        for (String classpath: classpaths) {
            urls.add(getURL(classpath));
        }
        URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[0]));
        Class<?> cls = loader.loadClass(main);
        Thread.currentThread().setContextClassLoader(loader);
        Method m = cls.getMethod("main", new Class[]{new String[0].getClass()});
        m.invoke(null, new Object[]{args});

    }

}

3


これには柔軟性があり、機能が豊富です。

  JarClassLoader jcl = new JarClassLoader();

  //Loading classes from different sources
  jcl.add("myjar.jar");
  jcl.add(new URL("http://myserver.com/myjar.jar"));
  jcl.add(new FileInputStream("myotherjar.jar"));
  jcl.add("myclassfolder/");

  //Recursively load all jar files in the folder/sub-folder(s)
  jcl.add("myjarlib/");

  JclObjectFactory factory = JclObjectFactory.getInstance();

  //Create object of loaded class
  Object obj = factory.create(jcl, "mypack.MyClass");

2


さらに編集:

私はウェブをスキャンして、あなたの質問にも関係があるかもしれないこの素晴らしい記事に出くわしました:http://www.szegedi.org/articles/remotejars.html

その場合、私が以下に書いたものの大部分は無関係ですが、万が一の場合に備えてそのままにしておきます。

編集する

わかりました、私はあなたの要求のよりよい映像を得ていると思います。 ただし、要件は難しいので、あなたが何をしようとしていると思うかを教えてください。次に、どの解決策が提案されているかを見ていきます。 私はおそらくこれを間違えるでしょう、それから我々は再びそれをします。

必要条件

WebStartアプリケーションを提供するための分散キャッシュメカニズム。 アプリケーション(.jar)は定期的に変更されます。 それらは自己完結型です。 中央サーバーから取得したWebstart jarファイルを提供し、メモリ内に保持できるローカルキャッシュが必要です。 Exitの要件がわかりません。

解決策は?

探しているのは、更新されたアプリケーションjarをメモリに読み込み、それらをwebstartランチャーに提供するwebappをホストできるwebサーバーです。 Jetty / TomcatなどのWebサーバーを使用し、その下で実行する簡単なwebappを作成する必要があります。 webappは、アプリケーションの更新のために中央サーバーをポーリングし、提供するURLを介してwebstartがアプリケーションjarを利用できるようにします。 中央サーバーをポーリングすることは、ファイアウォールと拡張性の理由から、中央サーバーに新しいアプリケーションをローカルサーバーにプッシュさせるよりも意味があります。

これを行う市販のWebアプリは知りませんが、あるかもしれません。

しかし、私が言ったように、私はおそらくまだこれを取得しません。 要件:それらを愛するようになった。

” ” ‘

あなたの質問に基づいて、この回答でいくつかの仮定を行います。 「app.jar」への変更から「load.jar」を分離できるようにするために、ローカルマシン上の「load.jar」の存続期間中、リモートマシンから「app.jar」をキャッシュしたいようです。 「その存続期間中。 これは良いアイデアのように思えます。URLClassLoaderを使用して「app.jar」を「load.jar」スペースに入れると、実行中の更新が大混乱を招く可能性があると思います。

また、「load.jar」に「app.jar」のディスクベースのコピーを作成させたくないように思えます-これは合理的な目標だと思います:古いjarファイルを機械? 一時ファイルを書き込もうとすることに関する許可の問題が必要な人はいますか?

これらの目標を考えると、「load.jar」がその中のクラスに最初にヒットしたときに「app.jar」のスナップショットを作成するクラスローダーを見つけるか実装する必要があります。 これは難しくありません。Jarファイルの内部からJarファイルをロードするOne-JAR JarClassLoaderで同様のことをしなければなりませんでした。 起動時に、見つかったすべてのバイトをメモリにロードし、そのメモリストアを使用してオンデマンドでクラスを解決します。 遅延読み込みよりも効率が低い可能性がありますが、高速で安定しており、問題を解決できます。

残念ながら、One-JARでは、ネットワーク(またはファイル)リソースをこの方法でキャッシュすることはできません。 通常のURLクラスローダーを使用して委任を使用するため、リモートリソースがキャッシュされません。

CVSリポジトリをご覧になることをお勧めします:http://one-jar.cvs.sourceforge.net/viewvc/one-jar/one-jar/src/com/simontuffs/onejar/JarClassLoader.java?revision=1.58 &view = markup

678行目あたり。 このクラスのサイズ、特別なケースを処理するための特別なケースの数に気を散らさないでください。

ゼロから何かを作成する必要がある場合は、URLClassLoaderをサブクラス化し、loadClass、getResource、およびfindResourceメソッドをオーバーライドします(たとえば、One-JARが独自のクラスローダーの反転の必要性のためにこれを行う行281を参照)。 「app.jar」全体を、クラス/リソース名キー(これもOne-JARです)によってインデックス付けされたバイト配列ハッシュマップとしてメモリにロードすると、メモリにキャッシュされます。

これが役に立つことを願っています。

-サイモン。

2


まだURLClassloaderクラスを見たことがありますか?

ここにあるJarClassloaderは役に立つかもしれません:http://www.java.happycodings.com/Other/code27.html

0


タイトルとURLをコピーしました