Why no /run/current-system/sw/share/java?

I have 2 NixOs installations, a server and a desktop,
I build some custom packages and a service for a java application.

It works fine, when I test it on the desktop, but when I move it to
the server it don’t work anymore.

The current main problem is that /run/current-system/sw/share/java don’t
exist on the server, but it does get build and merged correctly on the desktop.

The desktop’s system.stateVersion = “22.11” and
the server’s system.stateVersion = “23.05”

I also add some scripts in bin/


[nix-shell:/etc/nixos]# tree /nix/store/01d4f7qns94mg1sfh9f45zxs4ksw121x-corenlp-4.5.7/bin/
/nix/store/01d4f7qns94mg1sfh9f45zxs4ksw121x-corenlp-4.5.7/bin/
├── corenlp
└── corenlp-server

and they get merged correctly into

# which corenlp
/run/current-system/sw/bin/corenlp

# ls -ltr /run/current-system/sw/bin/corenlp
lrwxrwxrwx 1 root root 69 Jan  1  1970 /run/current-system/sw/bin/corenlp -> /nix/store/01d4f7qns94mg1sfh9f45zxs4ksw121x-corenlp-4.5.7/bin/corenlp

But /share/java don’t appear on the server, but they do exist in the package.

[nix-shell:/etc/nixos]# tree /nix/store/01d4f7qns94mg1sfh9f45zxs4ksw121x-corenlp-4.5.7/share/
/nix/store/01d4f7qns94mg1sfh9f45zxs4ksw121x-corenlp-4.5.7/share/
└── java
    └── corenlp
        ├── ejml-core-0.39.jar
        ├── ejml-core-0.39-sources.jar
        ├── ejml-ddense-0.39.jar
        ├── ejml-ddense-0.39-sources.jar
        ├── ejml-simple-0.39.jar
        ├── ejml-simple-0.39-sources.jar
        ├── istack-commons-runtime-3.0.7.jar
        ├── istack-commons-runtime-3.0.7-sources.jar
        ├── javax.activation-api-1.2.0.jar
        ├── javax.activation-api-1.2.0-sources.jar
        ├── javax.json-api-1.0-sources.jar
        ├── javax.json.jar
        ├── jaxb-api-2.4.0-b180830.0359.jar
        ├── jaxb-api-2.4.0-b180830.0359-sources.jar
        ├── jaxb-impl-2.4.0-b180830.0438.jar
        ├── jaxb-impl-2.4.0-b180830.0438-sources.jar
        ├── joda-time-2.10.5-sources.jar
        ├── joda-time.jar
        ├── jollyday-0.4.9-sources.jar
        ├── jollyday.jar
        ├── protobuf-java-3.19.6.jar
        ├── slf4j-api.jar
        ├── slf4j-simple.jar
        ├── stanford-corenlp-4.5.7.jar
        ├── stanford-corenlp-4.5.7-javadoc.jar
        ├── stanford-corenlp-4.5.7-models.jar
        ├── stanford-corenlp-4.5.7-sources.jar
        ├── xom-1.3.9-sources.jar
        └── xom.jar

3 directories, 29 files
type or paste code here

Why don’t /run/current-system/sw/share/java get build on my server :question:

By default, only a subset of paths under installed package’s /share get linked under the system directory.

If you really want /share/java to be included here, you can set environment.pathsToLink = [ "share/java" ].

2 Likes

You typically don’t want your package to use binary libraries from some global path. This is why the set of paths that get linked globally is rather restricted by default.

It’s better to encode exact paths in the package’s derivation from which it should take the dependencies or make the path relative to the package’s output path instead. This makes the package work hermetically; without any implicit dependencies such as /run/current-system/sw/share/java/.

2 Likes

Thanks, looking more into it. I found out ,

environment.pathsToLink = [ "/share/java" ];

, was the right answer.

I used,

nixos-option environment.pathsToLink

, to debug the problem.

And discovered that /share is used in the mate package.

/nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/services/x11/desktop-managers/mate.nix:      environment.pathsToLink = [ "/share" ];

That why there was a different between my desktop and my server.

I understand, but this is not my problem.

I have a main program, let’s call it M.

Then I have “databases” lets call them A B C D E F. etc.

A user will typical only install a few of the databases, since they are big.

But the main program, need to be able to find them. Since it is java, we
need to be able to construct a CLASSPATH with the databases, they are jar files.

When I install the main program, I can not know if some database is also installed.

But if installed in the same directory, then a CLASSPATH can be built at runtime.

If you know of another way of solving this problem, please let my know.

If you build everything with nix, you can use something like wrapProgram or makeWrapper to set envvars in the executable

I assume these “databases” are java libraries (jars) that the program loads at runtime?

If you need the runtime inputs to be optional and they do not need to be present in order to build the program itself, I’d employ a wrapper pattern. This would be another nix package that takes the runtime libs as an override input and simply calls makeWrapper on the java -jar command with the actual derivation’s main jar and it sets the CLASSPATH accordingly as @waffle8946 mentioned.

Yes, to your question.

I need to figure out what “override inputs” are.

I did use a makeWrapper, but not makeProgram. Maybe I can find some examples in the code base.

Here is a tread with some of the code.

But how do I build a CLASSPATH that contain information from different packages, so that I can write it via makeWrapper in the envvars?