Search code examples
dllexemaven-assembly-plugin

Maven Assembly Plugins corrupts exe dll


I'm trying to create a zip file containing, among other stuff of my Java project, a .NET x64 EXE + its manifest + a .NET DLL dependency. It looks like maven assembly plugin corrupts the EXE and the DLL. In fact if I try to execute the file once extracted I get "This app can't run on this PC" (invalid x64 windows application), but if I copy the original files they work normally.

I've tried to google for a solution without success. Am I missing something in maven files?

Plugin declaration in pom.xml is:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptors>
            <descriptor>src/main/assembly/windows.xml</descriptor>
        </descriptors>
    </configuration>
    <executions>
        <execution>
            <id>assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <appendAssemblyId>false</appendAssemblyId>
                <finalName>${bundle.name}</finalName>
            </configuration>
        </execution>
    </executions>
</plugin>

while windows.xml content is:

<?xml version="1.0"?>
<assembly
  xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
  <id>windows</id>

  <formats>
    <format>zip</format>
  </formats>

  <files>
    <file>
      <source>${launcher.dir}/GetMachineId.exe</source>
      <outputDirectory>bin/utils</outputDirectory>
      <destName>GetMachineId.exe</destName>
    </file>
    <file>
      <source>${launcher.dir}/GetMachineId.exe.config</source>
      <outputDirectory>bin/utils</outputDirectory>
      <destName>GetMachineId.exe.config</destName>
    </file>
    <file>
      <source>${launcher.dir}/MessagingToolkit.QRCode.dll</source>
      <outputDirectory>bin/utils</outputDirectory>
      <destName>MessagingToolkit.QRCode.dll</destName>
    </file>
  </files>
</assembly>

Solution

  • Found the issue.

    I was actually using also maven-resources-plugin on ${launcher.dir} with filtering.

    Excluding binary files from filtering solved the problem.

    UPDATE: In my pom.xml the maven-resources-plugin was configured like in the following:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
            <execution>
                <id>filtering-launcher-resources</id>
                <phase>process-resources</phase>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <outputDirectory>${launcher.dir}</outputDirectory>
                    <resources>
                        <resource>
                            <directory>src/main/launcher</directory>
                            <filtering>true</filtering>
                        </resource>
                    </resources>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    With src/main/launcher erroneously containing both text file (that actually required filtering) and binary ones (GetMachineId.exe, GetMachineId.exe.config, MessagingToolkit.QRCore.dll).

    In order to solve the problem I've moved those binaries in a different folder (utils) and modified the assembly file like this:

    <?xml version="1.0"?>
    <assembly
      xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
      <id>windows</id>
    
      <formats>
        <format>zip</format>
      </formats>
    
      <files>
        <file>
          <source>utils/GetMachineId.exe</source>
          <outputDirectory>bin/utils</outputDirectory>
          <destName>GetMachineId.exe</destName>
        </file>
        <file>
          <source>utils/GetMachineId.exe.config</source>
          <outputDirectory>bin/utils</outputDirectory>
          <destName>GetMachineId.exe.config</destName>
        </file>
        <file>
          <source>utils/MessagingToolkit.QRCode.dll</source>
          <outputDirectory>bin/utils</outputDirectory>
          <destName>MessagingToolkit.QRCode.dll</destName>
        </file>
        <file>
            <source>${launcher.dir}/config.xml</source>
            <outputDirectory>bin</outputDirectory>
            <destName>config.xml</destName>
        </file>
      </files>
    </assembly>
    

    This way maven-resources-plugin does not process with filtering the binaries, so they do not get corrupted. It looks like the filtering process treats always the files like they are text ones, so it modifies binaries in such a way that prevents their execution.

    Another, more recent, strategy could be this one: https://maven.apache.org/plugins/maven-resources-plugin/examples/binaries-filtering.html