How to Simulate Just One Enter in Command Line After Executing a Jar File

How can I create a jar file with an entry point inside a file tree?

See this tutorial. The argument for the jar command's e option should be a class name, not a path name. Furthermore, when specifying the list of classes to be included in the jar, care should be taken to reference the files such that the directory structure matches the package name. Otherwise the classpath lookups will fail. Try:

jar -cef a.MainClass formatter.jar -C bin .

Java Jar file main class run when runs from command line, but not from Windows batch file

Most likely explanation

Your paths are relative, which means that the batch file isn't going to work unless you run it from the right place. In general, having a batch file that has an invisible rider stapled to it with: "I break in mysterious ways if not run from the appropriate dir" is a crappy batch file - make it better.

Better solution

Or, even better, get rid of it. You don't need batch files to distribute java programs.

Proper ways to distribute java programs:

  • The modern take is very very different from what you have here: JREs are dead, you must ship an installer that does the whole thing, notably including a java runtime (no longer called a JRE, and one you ship and keep up to date if relevant). That's perhaps a bridge too far for what you're doing here. Relevant tools include jlink.

  • A slightly less modern take involves jars with manifests:

Your jar file should contain a manifest. This manifest must contain 2 relevant entries:

Class-Path: lda-services.jar bip-services-1.6.0.0-SNAPSHOT.jar decryptor-1.6.0.0-SNAPSHOT.jar slf4j-api-1.7.31.jar commons-io-2.6.jar

and

Main-Class: com.ilcore.util.SosaMaintenanceJFrame

You can use jar's -m switch, or just include the manifest (it's just a file in the jar): it's at META_INF/MANIFEST.MF and it's a text file, each line is an entry, and an entry consists of a key: value pair.

When a jar contains this, just double clicking the jar and running java -jar thejar.jar will then take care of it all: Java will load the stated jars as part of the classpath, and these, crucially, are resolved as paths relative to the directory the jar is in, so it DOES work when you try to launch them from elsewhere, i.e. if you do:

C:
CD \
java -jar "c:\Program Files\MyApp\myapp.jar"

it works fine, whereas that batch script would fail due to being in the wrong place.

Build systems let you define the manifest too, check your build systems docs for how to do this, it'll be easy, and there are tons of tutorials if you search the web for e.g. 'manifest executable jar maven' or whatnot.

  • You can consider making a shaded jar. But I wouldn't.

A shaded jar takes all your dependencies and packs them into your main jar, so that there is only one jar. There is now no need for a Class-Path entry (the jar you run is obviously already on the classpath and there's nothing else to include) and your app is shipped as 'just' a single jar file.

But this is mostly a red herring: There are no consumer JREs anymore so you've made the user experience from a D- to a D. If you actually care about giving your users a nice experience, there's no getting around an installation process of some sort and once you have that, having the separate jars is no longer a problem. Separate jars are less hairy when signed jars are involved, are much easier to keep up to date, and have a significantly faster turnaround (when you build your stuff and want to ship what you built, shading takes ages, so it's nice to cut that step out). The faster your CI system tells you about failing tests, the better.

  • Meet in the middle

You don't have to upgrade to modules and the like. What you can do instead is use something like launch4j. The aim is to end up with a zip file along with the installation instructions: Make a dir somewhere. unzip this zip in it. Doubleclick 'myapp.exe'. Done.

The zip would contain an entire JRE, all your jar file deps, and your main app, and an exe file which launch4j made for you, that launches your app using the JRE packed into the jar. This means you know exactly which JRE is being used, and it'll work even on systems that didn't have one installed yet (which, these days, should be all of them - the notion of 'end user downloads a JRE from oracle and the user + oracle work together to keep that thing up to date and security-issue-free', is dead).

The fact that it's an EXE is nice: Now if the user e.g. alt+tabs through their apps, they get your app, with your name, and your icon, instead of 'javaw.exe' with an ugly coffee mug logo.

How to execute a java main class from the command line

I find solution without modify my project:

mvn clean install
mvn exec:java -Dexec.mainClass=com.your.company.cli.Hello

How to stop a running *.JAR file with a batch script?

The following set of batch scripts can be used to start/stop jars/any program

start-jar.bat

start "win_title" java -jar [jar file] [jar options]

this basically starts your jar(the program) in a window with title set to "win_title".

you could use another batch to kill the window started

stop-jar.bat

TASKKILL /FI "WINDOWTITLE eq win_title

JUnit: How to simulate System.in testing?

It is technically possible to switch System.in, but in general, it would be more robust not to call it directly in your code, but add a layer of indirection so the input source is controlled from one point in your application. Exactly how you do that is an implementation detail - the suggestions of dependency injection are fine, but you don't necessarily need to introduce 3rd party frameworks; you could pass round an I/O context from the calling code, for example.

How to switch System.in:

String data = "Hello, World!\r\n";
InputStream stdin = System.in;
try {
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextLine());
} finally {
System.setIn(stdin);
}

Why does only the first line of this Windows batch file execute but all three lines execute in a command shell?

Maven uses batch files to do its business. With any batch script, you must call another script using the call command so it knows to return back to your script after the called script completes. Try prepending call to all commands.

Another thing you could try is using the start command which should work similarly.



Related Topics



Leave a reply



Submit