Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

jar

People also ask

Can we read code that is in JAR file?

Hi, Jar files are archive files that contains of a lot of different java classes (files). You can use winzip/winrar to open the jar files and you can see those java classes in jar files. Typically you can use a Java decompiler to decompile the class file and look into the source code.

How do I know if a JAR file is in use?

The only way to find out whether a JAR file is used at runtime is basically to take it out, start up your application and test every functionality. If you have an application of moderate size, performing a 100% regression test takes many hours.

What is runtime jar?

These jar files can be signed by an author using digital certificate. These jar files can be authenticated using digital certificates and checking the author's signature. The JRE (Java Runtime Environment) loads the classes from the JAR file without un-jarring it.

Can JRE run jar?

You need Java, to be more precise: jre, installed to run a jar file. It is possible to pack your program together with the needed runtime environment so that your program files contain the jre you need to run it.


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:"

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:file:/C:/Users/Jon/Test/foo.jar!/com/whatever/Foo.class

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
}

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

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.

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.


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.


If you query the JAR file name it will work if running from a JAR file otherwise it will return something like classes so the following code can be used:

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.MF should work:

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;
    }
}

Here is some code you can run from a normally or as a 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 cf test.jar TestApplet.class
java -cp test.jar TestApplet