本文介绍了在内存jar /类文件中执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在某个位置有一个jar文件(例如app.jar),可用作来自http服务器的文件/流。问题是app.jar本身是一个经常更新的jar文件,在服务器上定期更新。
我有另一个jar文件(比如load.jar),任何用户都可以下载。
在运行时,用户运行load.jar,这是在单独的进程中加载​​app.jar所需的,将app.jar保存在内存中(不缓存到磁盘),然后执行app.jar并终止本身(load.jar)。
有可能吗?任何帮助都非常感谢。
提前致谢。
问候,
KT

I have a jar file (say app.jar) in a certain location available as a file/stream from an http server. The problem is that app.jar is itself a frequently updated jar file being updated regularly at the server.I have another jar file (say load.jar) which is simply downloadable by any user.At runtime, the user runs the load.jar, which is required to load the app.jar in a separate process keeping the app.jar in memory (no cacheing to disk), then execute the app.jar and terminate itself (load.jar).Is it possible to be done? Any help is highly appreciated.Thanks in advance.Regards,KT

------------------------ ---更新。

---------------------------Update.

感谢大家的回复。但是,我想我还没有给出完整的图片。
图片 ,描述了该场景。
4罐(实际的通用执行器)托管在中央服务器上。这些经常更新(最初每天最多3-4次,最终每天一次)。
托管其中一个成员的本地服务器,该服务器已初始化。
本地服务器上的启动程序会下载所有4个二进制文件并将其保留在内存中 - 不会缓存到磁盘。这些jar文件是自给自足的,并且不依赖于本地服务器上的任何库 - 它们实际上是从本地服务器调用jar。
客户端jar最终由本地服务器托管,并通过本地服务器通过webapp按需转发给客户端。
此外,Launcher需要通过从单独的JVM中的服务器调用下载的Main jar来退出。

Thanks all for the reply. However, I guess I have not given a complete picture.An image link text is attached depicting the scenario.4 jars (the actual common executors) are hosted on a central server. These are updated frequently (probably 3-4 times a day initially down to once a day eventually).A local server at one of the member is hosted which is initialised.The launcher on the local server downloads all the 4 binaries and keeps it in memory - no cacheing to disk. These jar files are self-sufficient and are not dependent on any library on the "Local Server" - they in fact invoke jars from the "Local Server".The "client" jar eventually is hosted with the "Local Server" and forwarded to its clients on demand via webapp by the "Local Server".Also, the Launcher needs to exit by invoking the downloaded Main jar from the server in a separate JVM.

问候,
KT

Regards,KT

推荐答案

好的。在我将szegedi文章的链接放入我之前的回答(诚实)之前,我制作了一个可以处理URL的jar启动器原型。就像作者所说,这并不难,可能还不完整。附在下面。我认为这是你需要的1/3。您的用户说(类似):

OK. Before I put the link to the szegedi article into my previous answer (honest), I prototyped a jar-launcher that could handle URLs. Like the author said, it wasn't hard, probably isn't complete. Attached below. I think this is 1/3 of what you need. Your user says (something like):

java -jar load.jar

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

load.jar有两个角色:(1)调用JarLauncher(下面)作为其main class(2)在localhost端口上提供app.jar(在调用JarLauncher之前)。因此,load.jar读取其参数以确定要运行的应用程序。

load.jar has two roles: (1) invoke JarLauncher (below) as its main class (2) serve app.jar on a localhost port (before invoking the JarLauncher). load.jar therefore reads its arguments to figure out which app to run.

最后(硬位):你必须使URLClassLoader没有命中临时磁盘。正如塞格迪的文章所说,这并不容易。或者,你可以编写自己的网络感知类加载器,它不是磁盘缓存,就像我的第一个建议将URL作为来自URL连接的字节流加载到内存中,将其解码为JarInputStream,并满足对loadClass /的调用来自内存中的流的findResource。

Finally (the hard bit): you have to make URLClassLoader not hit the temporary disk. As the szegedi article said, that isn't easy. Alternatively, you can write your own network-aware classloader that doesn't disk-cache, like my first suggestion loading the URL into memory as a byte-stream from a URL connection, decoding it as a JarInputStream, and satisfying calls to loadClass/findResource from that in-memory stream.

你有很多工作要做。祝你好运。

You have quite a lot of work ahead of you. Good luck.

对许可证文本的大小表示道歉,但只要你不怪我(BSD)它就可以让你用代码做你喜欢的事情。

Apologies for the size of the license text, but it lets you do what you like with the code as long as you don't blame me (BSD).

- simon。

--simon.



/*
 * One-JAR(TM) (http://www.simontuffs.com/one-jar).  Copyright (c) 2004-2010,
 * P. Simon Tuffs (simon@simontuffs.com).   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 <jar-file.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 <jar-file.jar>");
            System.exit(1);
        }
        String jar = args[0];
        args = Arrays.copyOfRange(args, 1, args.length);
        List<URL> urls = new ArrayList<URL>();
        // 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});

    }

}

这篇关于在内存jar /类文件中执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 09:15
查看更多