你能否在运行时告诉你是否在jar中运行java?

34 java jar

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

我希望在jar中运行时可以执行一些操作,但是我不希望它们在从Eclipse运行时完成.

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

谢谢!

Dikla

Jon*_*eet 38

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

例如,采取这个程序:

public class Foo {

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

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

file:/C:/Users/Jon/Test/com/whatever/Foo.class
Run Code Online (Sandbox Code Playgroud)

从jar文件运行它:

jar:file:/C:/Users/Jon/Test/foo.jar!/com/whatever/Foo.class
Run Code Online (Sandbox Code Playgroud)

  • 我将这个问题解释为"从Eclipse创建的构建(即在bin目录中)和从jar文件中运行".没有提到在*Eclipse中使用jar文件*.这是一个模糊的问题. (5认同)

IT *_*man 8

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

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

第二:

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

  • 我认为向资源打开“URLConnection”在资源方面非常浪费,因此不是简单检查协议的“更好”解决方案。 (3认同)

Hos*_*Aly 6

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

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

您可以检查一些其他潜在的属性,您可以在Eclipse中找到它们Help -> About -> Configuration Details.

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

  • @foo 这个问题特别询问了有关检测它何时在 Eclipse 中运行的问题。其他答案展示了检测 JAR 的好方法。这增加了一种用于检测 Eclipse 的潜在解决方案。 (3认同)

Bul*_*aza 6

如果您查询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");
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

如果您需要更高的准确性并防止重命名文件扩展名,请检查文件是否包含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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Von*_*onC 5

从方法

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);
 }
}
Run Code Online (Sandbox Code Playgroud)

会给:

>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
Run Code Online (Sandbox Code Playgroud)

正如Hosam Aly所指出的,这并没有完全回答这个问题.
作为维基回答,我把它留在那里作为一般参考.

  • 嗯,这开始听起来像指纹识别……我认为在这一点上可能值得了解到底动机是什么。如果需要区分应用程序是否正在使用控制台运行,可以检查 System.console() == null 是否。当一个应用程序被eclipse启动时,它是null;但这是一个非常间接的推论。 (2认同)