Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 内存中jar/类文件执行_Java_Memory_Jar - Fatal编程技术网

Java 内存中jar/类文件执行

Java 内存中jar/类文件执行,java,memory,jar,Java,Memory,Jar,我在某个位置有一个jar文件(比如app.jar),可以作为http服务器的文件/流使用。问题在于app.jar本身就是一个频繁更新的jar文件,服务器上会定期更新。 我有另一个jar文件(比如load.jar),任何用户都可以下载它。 在运行时,用户运行load.jar,这是在单独的进程中加载app.jar所必需的,将app.jar保存在内存中(不缓存到磁盘),然后执行app.jar并终止自身(load.jar)。 有可能吗?非常感谢您的帮助。 提前谢谢。 当做 KT ------------

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

---------------------------更新

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

问候,,
KT

您看过URLClassloader类了吗


这里的JarClassloader可能很有用:

我建议您看看

这具有更好的灵活性,并且功能非常丰富

  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");
进一步编辑:

我浏览了一下网页,发现了这篇优秀的文章,这篇文章可能也与你的问题有关:

在这种情况下,我在下面写的大部分内容都是无关紧要的,但我还是留下来以防万一

编辑:

好的,我想我对你们的要求有了更好的了解。尽管需求很棘手,所以让我告诉您我认为您正在尝试做什么,然后我将看看建议的解决方案。我可能会弄错,然后我们再来一次

要求:

为WebStart应用程序提供服务的分布式缓存机制。应用程序(.jar)会定期更改。它们是独立的。您希望有一个本地缓存,能够为从中央服务器获得的Webstart jar文件提供服务,并将它们保存在内存中。我不明白你对退出的要求

解决方案

您可能正在寻找的是一个web服务器,它可以承载一个webapp,将更新的应用程序JAR读入内存,然后将它们提供给webstart启动器。您需要使用Jetty/Tomcat等web服务器,并编写一个简单的webapp在其下运行。webapp将轮询中央服务器以获取应用程序更新,并通过其提供的URL使webstart可以使用应用程序JAR。出于防火墙和可伸缩性的原因,轮询中央服务器可能比让中央服务器将新应用程序推送到本地服务器更有意义

我不知道有任何现成的网络应用程序可以做到这一点,可能有一个

但就像我说的,我可能还是不明白。要求:一定要爱他们


根据你的问题,我将在这个答案中做出一些假设。听起来您想在本地计算机上的“load.jar”的生存期内缓存远程计算机上的“app.jar”,以便在其生存期内将“load.jar”从对“app.jar”的更改中隔离出来。这似乎是个好主意:我认为如果您使用URLClassLoader将“app.jar”放入“load.jar”空间,那么在执行过程中进行更新可能会造成严重破坏

听起来你也不想让“load.jar”制作“app.jar”的基于磁盘的副本——我认为这是一个合理的目标:谁想让旧jar文件分散在机器上?谁想要与尝试写入临时文件相关的权限问题

考虑到这些目标,您需要找到或实现一个类加载器,当“load.jar”第一次命中“app.jar”中的一个类时,该类加载器生成“app.jar”的快照。这并不难:我必须在我的单JAR JarClassLoader中做类似的事情,它从JAR文件内部加载JAR文件。在启动期间,它将所有找到的字节加载到内存中,然后使用该内存存储按需解析类。虽然可能比惰性加载效率低,但它快速、稳定,可以解决您的问题

不幸的是,一个JAR不允许以这种方式缓存网络(或文件)资源。它通过一个普通的URL类加载器使用委托,这将使它不会缓存您的远程资源

我建议您查看一下CVS存储库:

在678号线附近。不要被这个班级的规模吓倒,这是一堆需要处理的特殊情况,嗯,特殊情况

如果我必须从头开始创建一些东西,我会将URLClassLoader子类化,重写loadClass、getResource和findResource方法(参见示例第281行,其中一个JAR为自己的类加载器反转需要这样做),通过加载整个“app.JAR”放入字节码缓存作为一个字节数组hashmap被类/资源名键索引到内存中(这又是一个JAR),然后您将被缓存在内存中

我希望这有帮助


--西蒙。好的。在我将szegedi文章的链接放入我之前的答案(诚实)之前,我原型化了一个可以处理URL的jar启动器。正如作者所说,这并不难,可能并不完整。附件如下。我想这是你需要的三分之一。您的用户说(类似于):

java-jar-load.jar

load.jar有两个角色:(1)调用JarLauncher(如下)作为其主类(2)在本地主机端口上服务app.jar(之前) /* * 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}); } }