Snapcraft binary jar application pack errors

Trying to build snap version of my java app which I’m expecting to be already built so I only need to include my jar file to the snap, but I can’t make it work. Lxd gives my timeouts even with firefall redirect config from the guide so I’m doing it with multipass, but I can’t even execute simple ‘ls’ command to test it out. Any ideas what might be wrong?

name: kanji-dojo
base: core22
version: '1.7'
summary: Kanji Dojo summary
description: |
  Kanji dojo description
  Test

architectures: [amd64]
grade: devel
confinement: devmode

apps:
  kanji-dojo:
    command: ls -l #java -jar $SNAP/jar/kanji-linux-x64-1.7.0.jar
    environment:
      JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
#      PATH: $JAVA_HOME/jre/bin:$PATH
    plugs:
      - home

parts:
  test:
    plugin: dump
    source: core/build/compose/jar
    source-type: local
    organize:
      '*': test/

I often get errors like

 container.go:215: in snap "kanji-dojo": path "ls" does not exist
2023-12-12 13:37:56.436 :: error: cannot pack "/root/prime": snap is unusable due to missing files

It can’t find java command either and I’m not sure what files are packed into the snap, tried with and without organize config, tried root folder like . (sometimes it says something about empty prime or something)

Snaps are self contained and confined… you will need to ship your own java interpreter via a stage-packages entry and point your JAVA_HOME variable to it…

If you change your command: to something like ls the same applies, you need to make sure ls is on your snap…

1 Like

Hi,

You will need something like this:

name: kanji-dojo
base: core22
version: '1.7'
summary: Kanji Dojo summary
description: |
  Kanji dojo description
  Test

architectures: [amd64]
grade: devel
confinement: devmode

apps:
  kanji-dojo:
    command: java -jar $SNAP/jar/kanji-linux-x64-1.7.0.jar
    environment:
      JAVA_HOME: $SNAP/usr/lib/jvm/java-17-openjdk-amd64/
      PATH: $JAVA_HOME/bin:$PATH
    plugs:
      - home

parts:
  jre:
    plugin: nil
    stage-packages:
    -  openjdk-17-jre

  test:
    plugin: dump
    source: core/build/compose/jar
    source-type: local
    organize:
      '*': test/
  1. You will need add JRE as stage-packages to the snap.
  2. Use $SNAP for your paths since you cannot access outside of snap.
  3. If you try to debug it, use snapcraft pack --debug if it build failed. You will get a terminal for you to run commands and check what happened.
2 Likes

Thanks for the tip. I tried to update config according to your sample and my small fixes, but unfortunately it still can’t find java.

13 12:13:19.919116 container.go:215: in snap "kanji-dojo": path "java" does not exist
2023-12-13 12:19:15.878 :: error: cannot pack "/root/prime": snap is unusable due to missing files

I tried to run snapcraft with debug flag and explore different folders. As I understand I have to take a look at /root/prime directory since it will be my resulting snap. I noticed that all my source code is there, not just core/build/compose/jars but also additional folder test/ with my jar file and usr with jvm bin deep inside of it (and I found a wrong folder in the path env variable, but fixing it didn’t help)

So I have following files I need /root/prime/test/kanji-linux-x64-1.7.0.jar /root/prime/usr/lib/jvm/java-17-openjdk-amd64/bin/java

And my final yaml

name: kanji-dojo
base: core22
version: '1.7'
summary: Kanji Dojo summary
description: |
  Kanji dojo description
  Test

architectures: [amd64]
grade: devel
confinement: devmode

apps:
  kanji-dojo:
    command: java -jar $SNAP/test/kanji-linux-x64-1.7.0.jar
    environment:
      JAVA_HOME: $SNAP/usr/lib/jvm/java-17-openjdk-amd64
      PATH: $JAVA_HOME/bin:$PATH
    plugs:
      - home

parts:
  jre:
    plugin: nil
    stage-packages:
      - openjdk-17-jre
  test:
    plugin: dump
    source: core/build/compose/jars/
    source-type: local
    organize:
      '*': test/

I also tried to remove $SNAP/ in JAVA_HOME with no luck and as I understood envs during debug aren’t the same as they’ll be in runtime. Any other tips?

try changing it to:

command: usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar $SNAP/test/kanji-linux-x64-1.7.0.jar

(or use a wrapper script that uses $JAVA_HOME/bin/java if you do not like the long command: entry)

1 Like

Yeah, it worked, I wonder why envs didn’t work

Here is my final snapcraft.yaml for jetpack compose multiplatform application. Now it’s time to suffer trying to make desktop shortcut :sweat_smile:

name: kanji-dojo
base: core22
version: '1.7'
summary: Kanji Dojo summary
description: |
  Kanji dojo description
  Test

architectures: [amd64]
grade: devel
confinement: devmode

apps:
  kanji-dojo:
    command: usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar $SNAP/kanji-linux-x64-1.7.0.jar
    plugs:
      - desktop
      - home

parts:
  jre:
    plugin: nil
    stage-packages:
      - openjdk-17-jre
  app:
    plugin: nil
    source: core/build/compose/jars
    override-build: |
      mkdir -p $SNAPCRAFT_PART_INSTALL/
      cp *.jar $SNAPCRAFT_PART_INSTALL/

You actually want to keep the environment lines … they will be set during runtime of the app inside the confinement… snapcraft is just not clever enough to resolve them on the fly during build

Older versions of Snapcraft would have actually accepted command: java... by itself, but it was intentionally decided that the command: value should be deterministic. I.E rather than Snapcraft guessing Java might be in $SNAP/bin or elsewhere, it was made a requirement the developer points specifically to the exact binary.

So something like

apps:
  kanji-dojo:
    command: java -jar $SNAP/jar/kanji-linux-x64-1.7.0.jar

Actually could have worked on Core18 (and possibly 20?) but certainly by Core22 that’s considered unsupported.

By modern standards, the command always needs to be relative to $SNAP at runtime or $CRAFT_PRIME at build-time, and if the path doesn’t point exactly to a file that exists, Snapcraft won’t attempt to guess what you meant, it forces you to correct the mistake instead.