2

I just want to be able to do ./whatever.jar instead of java -jar whatever.jar.

I've found a way:

#!/bin/bash java -jar $0 $* exit # jar goes here... 

but it doesn't work. Java just complains that it's an invalid/corrupt jarfile.

I also tried piping:

#!/bin/bash tail -n +4 $0 | java -jar exit # jar goes here... 

but this doesn't work.

One way to do it is to somehow split the file into two separate parts (the script part and the jar part), and then execute the jar, but that'd be redundant. You'd might as well make a script that executes the jar and execute that script.

So I need to figure out how to somehow tail it and fake the file.

I thought I could do it using /dev/stdout:

#!/bin/bash java -jar /dev/stdout tail -n +5 $0 exit # jar goes here... 

That doesn't work either. It just prints the contents of the jar and java complains that it's invalid. (I figured out later that there's nothing to read in /dev/stdout)

So I need to read from stdout some other way. I really wish I could pipe it though. It would make things SO much easier :)

3
  • I don't think this is a doable thing, other than "make some other script that runs java -jar myjar.jar itself. Commented Jun 15, 2012 at 15:42
  • How did you create your script in the first version? Did you include a valid MANIFEST file? Please supply the commands that you used. Commented Jun 15, 2012 at 15:51
  • You may have to consider tools like launch4j.sourceforge.net. Commented Jun 15, 2012 at 15:52

6 Answers 6

4

You need a service called jexec some linux distros come with this installed check for /etc/init.d/jexec. My CentOS 5.5 definitely does.

What it does is register the jexec interpreter with the binfmt system.

For more information you might what to have a quick read of binfmt_misc.

Sign up to request clarification or add additional context in comments.

1 Comment

I don't have jexec (Kubuntu 12.04, OpenJDK 6)
2

Assuming you have the kernel source code installed, check out /usr/src/linux/Documentation/java.txt for a way to run Java code directly using the kernel's BINFMT_MISC support (assuming it's compiled into the version of the kernel you're running, but I think it is on most major distros). If you don't have the source installed, you should be able to find it online easy enough (here's one example).

3 Comments

I actually found this after seeing @Gareth Davis's answer
It'd be a good idea to put it in fstab, since it doesn't work after reboot otherwise.
1

FYI, if you wanted to do it your original way it would go like this:

$ cat jar.sh #!/usr/bin/env bash java -jar <(tail -n +4 "$0") exit $ cat jar.sh runme.jar > works.jar $ chmod a+x works.jar $ ./works.jar 

Presuming a recent bash with support for <()

2 Comments

@bi99l35: Of course it works. If you have a problem, post the error you get.
Invalid or corrupt jarfile /dev/fd/63 - That makes sense, since block devices are not regular files.
1

java -jar does not work with stdin, apparently it does some seeks rather than straight reads. On a system you can't mod, you have to use a tmp. for example.

#!/bin/bash JF=/tmp/junk$$.jar (uudecode -o /dev/stdout >$JF;java -jar $JF;unlink $JF) <<JAR begin-base64 644 junk.jar UEsDBBQACAAIAEaBz0AAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMA UEsHCAAAAAACAAAAAAAAAFBLAwQUAAgACABGgc9AAAAAAAAAAAAAAAAAFAAA AE1FVEEtSU5GL01BTklGRVNULk1G803My0xLLS7RDUstKs7Mz7NSMNQz4OVy LkpNLElN0XWqBAmY6RnEG5koaASX5in4ZiYX5RdXFpek5hYreOYl62nycvkm ZubpOuckFhdbKWSV5mXzcvFyAQBQSwcIBHn3CVkAAABZAAAAUEsDBBQACAAI AEd+z0AAAAAAAAAAAAAAAAAKAAAAanVuay5jbGFzc21QTUvDQBB926RJE6Ot ramfhXoQogcDXiteBPFQVIjowdOmXcrGZCMxEfxZelDw4A/wR4mzUShCF3Zn 9s2bt2/26/vjE8ARBi4stB10sNpC10UPazZ8G30G61gqWZ4wGMH+DYN5mk8F Q3sslbioslgU1zxOCTEzLhVDP7gbJ/yJhylXszAqC6lmI93oRnlVTMSZ1GQn qdT9oeZ5sNGyse5hA5sM3rlI03x4mxfpdNfGlodt7JC45jN05sqXcSIm5T8o en4sRUZG84oK/q8NmYdX5KEkJ4JnI4beApjBftC3lAbwg0X+MUSTvkivBm3y DJqCsgFFRrF58A72QglNSqdVg5qyBO+PuketGnVe0egabzDndLdWNUjVJGS5 fmXlB1BLBwjDUWL/IAEAAJ4BAABQSwECFAAUAAgACABGgc9AAAAAAAIAAAAA AAAACQAEAAAAAAAAAAAAAAAAAAAATUVUQS1JTkYv/soAAFBLAQIUABQACAAI AEaBz0AEefcJWQAAAFkAAAAUAAAAAAAAAAAAAAAAAD0AAABNRVRBLUlORi9N QU5JRkVTVC5NRlBLAQIUABQACAAIAEd+z0DDUWL/IAEAAJ4BAAAKAAAAAAAA AAAAAAAAANgAAABqdW5rLmNsYXNzUEsFBgAAAAADAAMAtQAAADACAAAAAA== ==== JAR 

Comments

1

Or I could just install the jarwrapper (Ubuntu) package.

Comments

0

Write a separate shell script:

whatever.sh

#!/bin/bash java -jar whatever.jar $* 

You can't make the JAR file directly executable because it's not an executable file. It's Java bytecode which can't be read directly by the machine nor any standard shell interpreter that I know of.

2 Comments

That's not really what I'm looking for though. I just want to be able to do ./whatever.jar!
The problem is, Java bytecode isn't executable, nor is it a script. When you use ./ to execute something, the shell expects one of those two.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.