2017-03-07 164 views
1

我有一个用maven构建的小应用程序:使用“java -jar executable.jar”执行Jar即可,但即使具有执行权限,“./executable.jar”也会返回“Bad Magic Number”

  <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-assembly-plugin</artifactId> 
      <configuration> 
       <archive> 
        <manifest> 
         <mainClass>be.scripts.batchconverter.MainScript</mainClass> 
        </manifest> 
       </archive> 
      </configuration> 
      <executions> 
       <execution> 
        <id>create-executale-jar</id> 
        <phase>package</phase> 
        <goals> 
         <goal>single</goal> 
        </goals> 
        <configuration> 
         <finalName>batchconverter</finalName> 
         <appendAssemblyId>false</appendAssemblyId> 
         <descriptorRefs> 
          <descriptorRef>jar-with-dependencies</descriptorRef> 
         </descriptorRefs> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 

我可以用“Java的罐子batchconverter”运行它,但是当我尝试用“使用chmod + X batchconverter.jar”,然后“./batchconverter.jar”来执行它,我得到这个通用的错误:

invalid file (bad magic number): Exec format error 

我的JDK是oracle,“1.8.0_121”,我已经安装了binfmt-support,并且正在运行一个ubuntu 16.04

这里是清单:

Manifest-Version: 1.0 
Archiver-Version: Plexus Archiver 
Built-By: jschoreels 
Created-By: Apache Maven 3.3.9 
Build-Jdk: 1.8.0_121 
Main-Class: be.scripts.batchconverter.MainScript 

和LS造成(证明X许可)

-rwxrwxr-x 1 jschoreels jschoreels 4,9M Mär 7 11:40 batchconverter.jar 

任何想法,以确定原因?

+0

我认为你可以只执行其他语言如bash,C/C++,而不是你可以用内容java -jar ex.jar编写执行脚本execute.sh,然后chmod a + x execute.sh等./execute。 sh可能会工作 – HRgiger

回答

2

大多数文件格式以字节或“幻数”的固定组合开始。
例如Java类文件以字节或“幻数”0xcafebabe开头。

您的系统需要能够识别文件的类型并知道要执行文件的内容。
您的系统不知道如何直接执行jar档案,并且unix系统被配置为这样做是非典型的。

在Ubuntu它是possible to enable this with the binfmt-support package.

另一个解决方案是嵌入开始script into the head of the archive file,但它是一个位哈克。
基本上操作系统将文件识别为shell脚本,然后脚本本身调用java命令。

例如spring-boot plugin is able to make use of this technique,它们嵌入了一个脚本,它允许直接执行jar文件,并且可以作为init启动 - 停止脚本使用。

+0

谢谢你的回答。但是,我已经安装了binfmt-support,jar是+ rw,而且我又有同样的错误。 –

+0

如果你刚刚安装了它,我会注销并再次登录,以确保它在路上。同时执行'update-binfmts --display'来查看是否启用了java配置。 – Magnus

2

TL; DR - 这是行不通的。使用java -jar ...

在JAR文件上设置执行权限并不会使它像可执行文件那样可执行。

在Linux/UNIX/Mac OSX上,操作系统将查看文件的前几个字节(即“幻数”),以决定在尝试执行该操作时要执行的操作。

  • 如果前3个是'E','L','F'后跟版本字节,则该文件是ELF格式的本机可执行文件。操作系统加载并执行它。
  • 如果前3个是'#','!','/'后跟根相对路径名,则该文件是可执行脚本。路径名告诉操作系统使用什么脚本解释器。操作系统启动解释器并将脚本路径名传递给它。其他(本地)可执行文件可以被其他OS风格识别。

对于JAR文件,如果试图以这种方式执行操作系统,操作系统不理解“幻数”。


请注意,它通常不是尝试理解幻数的shell。而是shell调用execve系统调用,传递可执行文件的文件名及其参数和环境变量。操作系统试图了解该文件的幻数,并失败。然后,execve系统调用返回ENOEXEC错误编号,该编号将shell转换为您看到的错误消息。