Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behavioral differences between conveyor run and conveyor make app #56

Closed
ennerf opened this issue Apr 6, 2023 · 9 comments
Closed

Behavioral differences between conveyor run and conveyor make app #56

ennerf opened this issue Apr 6, 2023 · 9 comments

Comments

@ennerf
Copy link

ennerf commented Apr 6, 2023

Describe the bug
I'm trying to package an FXSampler based app (see chart-fx#580). conveyor run behaves as expected, but conveyor make windows-app and running the executable doesn't find the samples (uses reflection).

Can you think of anything that would be different between the run and make app commands?

To Reproduce
Steps to reproduce the behavior:

  1. checkout the branch in chart-fx#580
  2. clean package -DskipTests --projects chartfx-samples -am (using JDK 15)
  3. cd chartfx-samples
  4. conveyor run (works)
  5. conveyor make windows-app and double-click the .exe (does not work)

Expected behavior
Both versions should act the same.

Screenshots

conveyor run conveyor make windows-app
image image

Desktop (please complete the following information):

  • OS: Windows 10
@mikehearn
Copy link
Member

That's very weird. Off hand I can't think of what could cause that. The run command is extremely simple. It literally just triggers the build of the app task, and then locates the first entry point and runs it.

What's the exception?

Random things to try:

  • Use make app --rerun to clear the cache? Hard to imagine how it might cause problems.
  • How are you running the exe? Is it possible there's a dependency on argv[0] being relative/absolute or something like that?

@ennerf
Copy link
Author

ennerf commented Apr 6, 2023

How are you running the exe? Is it possible there's a dependency on argv[0] being relative/absolute or something like that?

Good call. That "fixed" it. It seems to execute correctly when the working directory is anything other than bin. It makes no difference whether the execution path is absolute or relative.

The code is just calling into ControlsFX, so I have a feeling this will be a pain to debug... 😠

import fxsampler.FXSampler;

public class ChartFxSampler {
    public static void main(String[] args) {
        FXSampler.main(args);
    }
}

It doesn't look like a Conveyor issue, so I'll go ahead and close it.

@ennerf ennerf closed this as completed Apr 6, 2023
@mikehearn
Copy link
Member

It might still be an issue - maybe when argv[0] isn't a path our custom JNI launcher code isn't doing something that the java binary would and that's an appcompat issue. When you find the difference let us know. It could be as simple as a one line fix on our end.

@ennerf
Copy link
Author

ennerf commented Apr 6, 2023

I found nothing on the app side 😔

@ennerf ennerf reopened this Apr 6, 2023
@mikehearn
Copy link
Member

OK, I'll take a look when I get a chance. What's the stack trace?

@ennerf
Copy link
Author

ennerf commented Apr 7, 2023

There is only a lack of samples, so there is no stack trace. I just found the issue though:

It's using an older version of FXSampler that searches for jars/directories at or below the working directory: SampleScanner.java#L173-L197.

  • conveyor run works because the working directory is the project path, so it's finding the jars/classes from the target directory
  • running from below bin/.. or from app/ works because it's in the search path
  • running from bin/ or legal/ doesn't work

The latest version unfortunately only loads examples on the module path, so that one doesn't work at all.

@ennerf
Copy link
Author

ennerf commented Apr 7, 2023

Afaik there is no way to change the working directory post VM startup, so besides fixing it upstream (the right thing to do), I can think of a few workarounds:

  • add -Duser.dir=<appDir> on the VM options
    Is there by any chance some template that inserts the correct path when the native wrapper gets executed?

  • figure out which executable called it and run it again in another process with an appropriate working dir.
    Is there a simple-ish way to get the name and path of the executable without special casing every platform?

Update
I worked around it by placing a custom version that gets loaded by the classloader before the original one. That should work until there is a fix upstream.

@ennerf ennerf closed this as completed Apr 7, 2023
@mikehearn
Copy link
Member

I'm not sure overriding user.dir would work, but you could try this:

app.jvm.system-properties.user.dir = &&/../

and see if it affects the working directory. && is a special token that means "the place where the exe is found".

Presumably you can't use the existing samples as auto modules?

A couple of alternatives that spring to mind:

  1. If there's no console attached, set the default working directory to the root of the app package in the C++ EXE we provide that runs before the JVM starts up.
  2. A tool that auto-module-ifies a classpath (i.e. combines jars, computes a module descriptor for them all)

I've been meaning to do (2) for ages but never got around to it. Like, give it a Maven coordinate or some inputs and it'd spit out a "real" module, so like auto-mods but better because they'd have real dependency data and jlink would accept them.

@ennerf
Copy link
Author

ennerf commented Apr 7, 2023

Thanks, the &&/.. works and is a nicer workaround 👍

It's not my project, so modularizing it is out of scope. I figured I could quickly add a conveyor configuration, but I completely underestimated the brittleness of the ControlsFX Sampler project.

RE (2) I've run into so many issues with modules that I stopped trying to have fully-modularized projects. I've also tried adding a combined module descriptor with moditect to a shaded/shrunk jar, but I ran into some issues with that too. It'd be nice to have a tool that reliable takes care of it, but please add a flag to disable it in case something goes wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants