Bean
Bean

Reputation: 23

SBT assembly output 0xEFBFBD instead of 0xCAFEBABE in class file

Tools Version
OS Win10
JavaJDK 11
Scala 2.13.5
SBT 1.3.13
Assembly 2.1.0

The repository of sbt-assembly

  1. The Error message.

I run assembly in sbt shell and it prints [success].

Then I try to run the output .jar with java -jar MyProject.jar in cmd, and get this error:

java.lang.ClassFormatError: Incompatible magic value 4022320623 in class file Main

The same error message as this one: Java Incompatible magic value 4022320623

But all my work are done locally without any upload or download operation.

  1. The header of the class files.

I decompression the .jar package and find that all .class files are started with 0xEFBFBD EFBFBD, which means the character cannot be recognized by UTF-8.

I've run sbt package before, in that case, every java class file is started with 0xCAFE BABE.

I compared these two class files in binary form. Most of them are the same, but the one generated by assembly command has several 0xEFBFBD in it.

  1. What I'm trying to do.

I'm trying to assembly a large project with multiple modules to one .jar file.

I tried everything I can to make sure all the files are encoded & decoded in UTF-8.

  1. Other versions of assembly.

I also tried sbt-assembly releases 2.1.1 and 2.0.0, and got the same results.

I need to customize the Merge Strategy which is supported after 2.0.0, so I didn't try more versions.

I can't show any code here since I don't have right to do so. But if you need more information about this issue please let me know.

Upvotes: 2

Views: 280

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51683

It's hard to say without libraryDependencies and assemblyMergeStrategy of your build.sbt and without a specific class of assembly jar that is not valid.

I suspect that MergeStrategy.concat or MergeStrategy.filterDistinctLines was incorrectly applied to some .class files and this leads to not valid class files. MergeStrategy.concat / filterDistinctLines are for config files, .properties files, service files (i.e. files with names com.example.SomeInterface and contents com.example.impl.SomeImplementation) etc., not for .class files.

You can temporarily change assemblyMergeStrategy to

assembly / assemblyMergeStrategy := {
  case _ => MergeStrategy.singleOrError
}

to see all the duplicates, or to

ThisBuild / assemblyMergeStrategy := {
  case PathList(ps @ _*) if ps.last endsWith ".class" => MergeStrategy.singleOrError
  case x =>
    val standardStrategy = (ThisBuild / assemblyMergeStrategy).value
    standardStrategy(x)
}

to see all the .class duplicates. You should see among them the class files that become not valid upon MergeStrategy.concat/filterDistinctLines.

Sbt 1.3.13 is quite old, current is 1.8.2.

Upvotes: 2

Related Questions