如果您在 jar 中运行 java,您能告诉运行时吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/482560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:35:20  来源:igfitidea点击:

Can you tell on runtime if you're running java from within a jar?

javajar

提问by Jon Skeet

I have an application that some of my users run from Eclipse, and others run it by using a jar file.

我有一个应用程序,我的一些用户从 Eclipse 运行,其他用户使用 jar 文件运行它。

I want some actions to be done when running from within the jar, but I don't want them to be done when running from Eclipse.

我希望在从 jar 中运行时完成一些操作,但我不希望在从 Eclipse 运行时完成它们。

Is there a way to know on runtime whether the current application is running from within a jar?

有没有办法在运行时知道当前应用程序是否在 jar 中运行?

Thanks!

谢谢!

Dikla

迪克拉

回答by Jon Skeet

Well, you can tell whether or not a class has been loaded from a JAR file - use Foo.class.getResource("Foo.class")and see whether the returned URL begins with "jar:"

好吧,您可以判断一个类是否已从 JAR 文件加载 - 使用Foo.class.getResource("Foo.class")并查看返回的 URL 是否以“jar:”开头

For example, take this program:

例如,拿这个程序:

public class Foo {

    public static void main(String[] args) {
        System.out.println(Foo.class.getResource("Foo.class"));
    }
}

Running it loading the file from the file system:

运行它从文件系统加载文件:

file:/C:/Users/Jon/Test/com/whatever/Foo.class

Running it from a jar file:

从 jar 文件运行它:

jar:file:/C:/Users/Jon/Test/foo.jar!/com/whatever/Foo.class

回答by IT man

I have two better solutions. first:

我有两个更好的解决方案。第一的:

URL url = this.getClass().getClassLoader().getResource("input.txt");
URLConnection urlConnection = url.openConnection();
if (urlConnection instanceof JarURLConnection) {
    // run in jar
} else {
    // run in ide
}

second:

第二:

String protocol = this.getClass().getResource("").getProtocol();
if(Objects.equals(protocol, "jar")){
    // run in jar
} else if(Objects.equals(protocol, "file")) {
    // run in ide
}

回答by Hosam Aly

You could check the system class path property for the Equinox launcher:

您可以检查 Equinox 启动器的系统类路径属性:

if (System.getProperty("java.class.path").contains("org.eclipse.equinox.launcher")) {
    System.out.println("You're running inside Eclipse");
}

There are some other potential properties that you may check for, which you can find in Eclipse through Help -> About -> Configuration Details.

您还可以检查其他一些潜在的属性,您可以在 Eclipse 中通过Help -> About -> Configuration Details.

Jon's answer is good if you want to know whether you'r running from a JAR versus running from a bunch of class files. But if you use a JAR in both cases then it won't tell you what you need.

如果您想知道是从 JAR 运行还是从一堆类文件运行,Jon 的回答很好。但是如果你在这两种情况下都使用 JAR,那么它不会告诉你你需要什么。

回答by VonC

From How-To

操作方法

package com.rgagnon;

public class HelloClass {
 public static void main(String[] args) {
    new HelloClass().say();
 }

 public void say() {
   String className = this.getClass().getName().replace('.', '/');
   String classJar =  
     this.getClass().getResource("/" + className + ".class").toString();
   if (classJar.startsWith("jar:")) {
     System.out.println("*** running from jar!");
   }
   System.out.println(classJar);
 }
}

Will give:

会给:

>jar cvfm Hello.jar manifest.mft com\rgagnon\HelloClass.class
added manifest
adding: com/rgagnon/HelloClass.class (in=1059) (out=601) (deflated 43%)

>java com.rgagnon.HelloClass
file:/C:/DEV/WORK/JAVA/com/rgagnon/HelloClass.class

>java -jar Hello.jar
*** running from jar!
jar:file:/C:/DEV/WORK/JAVA/Hello.jar!/com/rgagnon/HelloClass.class


As pointed out by Hosam Aly, this does not answer exactly the question.
I leave it there for general reference, as a wiki answer.

正如Hosam Aly所指出的,这并不能准确回答问题。
我把它留在那里作为一般参考,作为 wiki 答案。

回答by BullyWiiPlaza

If you query the JARfile nameit will work if running from a JARfile otherwise it will return something like classesso the following code can be used:

如果您查询JAR文件名,它将在从JAR文件运行时起作用,否则它将返回类似classes的内容,因此可以使用以下代码:

import java.io.File;

public class JarUtilities
{
    public static String getJarName()
    {
        return new File(JarUtilities.class.getProtectionDomain()
                                .getCodeSource()
                                .getLocation()
                                .getPath())
                       .getName();
    }

    public static boolean runningFromJar()
    {
        return getJarName().contains(".jar");
    }
}

EDIT:

编辑:

If you need more accuracy and to be resistant against renaming of the file extension, checking whether the file contains the MANIFEST.MFshould work:

如果您需要更高的准确性并防止重命名文件扩展名,请检查文件是否包含MANIFEST.MF应工作:

public static boolean runningFromJAR()
{
    try
    {
        String jarFilePath = new File(JarUtilities.class.getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .getPath()).
                toString();
        jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");

        try (ZipFile zipFile = new ZipFile(jarFilePath))
        {
            ZipEntry zipEntry = zipFile.getEntry("META-INF/MANIFEST.MF");

            return zipEntry != null;
        }
    } catch (Exception exception)
    {
        return false;
    }
}

回答by AtlasMeh-ed

Here is some code you can run from a normally or as a jar.

下面是一些您可以从普通或作为 jar 运行的代码。

import java.applet.Applet;
import java.net.URL;
import java.security.CodeSource;

public class TestApplet extends Applet {

    public TestApplet(){    
        URL path = TestApplet.class.getResource("TestApplet.class");

        if(path.toString().startsWith("jar:"))
            System.out.println("I'm in a jar");
        else
            System.out.println("I'm not in a jar");
    }

    public static void main(String args[]) throws Exception{
        new TestApplet();
    }
}

To put it in a jar and run it use the following:

要将其放入 jar 并运行它,请使用以下命令:

jar cf test.jar TestApplet.class
java -cp test.jar TestApplet

回答by Thorbj?rn Ravn Andersen

Another approach is putting information in the manifest file, and testing for if that information is available at runtime.

另一种方法是将信息放入清单文件中,并测试该信息在运行时是否可用。

If it is, then the code was started with "-jar". Otherwise it was started in another way, e.g. directly from Eclipse.

如果是,则代码以“-jar”开头。否则,它会以另一种方式启动,例如直接从 Eclipse 启动。

回答by Brother Logic

You could try:

你可以试试:

boolean inJar = false;

try
{
  CodeSource cs = DataResolver.class.getProtectionDomain().getCodeSource();
  inJar = cs.getLocation().toURI().getPath().endsWith(".jar");
}
catch (URISyntaxException e)
{
e.printStackTrace();
}

If you're running from a jar file then cs.getLocation().toURI() will give you the URI of that file; if you're running from inside Eclipse then it'll probably be the path to directory containing your class files.

如果您从 jar 文件运行,则 cs.getLocation().toURI() 将为您提供该文件的 URI;如果您从 Eclipse 内部运行,那么它可能是包含类文件的目录的路径。