jdeploy icon indicating copy to clipboard operation
jdeploy copied to clipboard

Initial thoughts, concerns and feature requests

Open marius-m opened this issue 2 years ago • 3 comments

Hi,

First of all, I love the idea and effort behind this project. As a hobbyist for JavaFx dev, I recognize the single and most important and complex thing is to ensure software is up-to-date and distribution.

Also, I’m playing with the idea of using this as a distribution. Especially this is a problem with updates + code sign on mac.

However, I have a few concerns about the longevity and maintenance of the project. So I had a few questions that maybe you could help me out in solving.

Concerns

  1. Project uses libraries in jars instead of maven repo
    • Won’t this be a problem when libraries will need to be updated?
    • There’s no way of knowing which version is used by the local library 🤷‍️
  2. Project uses other projects from repositories copied over instead of a submodule
    • I guess my concern is, if there is a new fixes / releases, how do you update it?
    • Another concern, the project that you’re using is 4 years old (last commit). Over the years, I’ve had so much trouble in solving platform compatibility on its distribution. I’m think that this library cannot be an exception 🤔
  3. Style of code
    • First of all, this is just my opinion, and I’m not saying its bad. I would love to contribute to the project and tinker with it.

    • I don’t understand empty lines in code and when should use it?

    • Sample code 1

      public class Bundler {
          public static int verboseLevel = 0;
      
      
      
      
          public static void main(String ... args) throws Exception {
              <...method content...>
          }
      
      
      
          /**
           * Returns first non-empty value from candidates
           * @param candidates
           * @return
           */
          private static String val(String... candidates) {
              <...method content...>
          }
      
          private static String toDataURI(URL url) throws IOException {
              <...method content...>
          }
      
          public static BundlerResult runit(AppInfo appInfo, String url,
                  String target,
                  String DEST_DIR,
                  String RELEASE_DIR) throws Exception {
      
      
      
      
      
              AppDescription app = new AppDescription();
              app.setNpmPrerelease(appInfo.isNpmAllowPrerelease());
              app.setName(appInfo.getTitle());
              app.setFork(appInfo.isFork());
              URL iconURL = URLUtil.url(appInfo.getAppURL(), "icon.png");
              app.setIconDataURI(toDataURI(iconURL));
      
      
              if (url == null) throw new IllegalArgumentException("URL is required. It can be a file: url");
      
      <...rest of class...>
      

Feature requests

Also, I was thinking about a few feature requests. Even thinking of maybe contributing to them myself 🤔

  1. Modularize distribution

    • It seems to me that there is no way to distribute (at least documentation does not state it so) only on NPM and ignore uploading to jdeploy.com/~app ?
    • Documentation how to set-up using a custom repository, where app could be downloaded.
  2. Customize launch

    • Change splash screen with custom images that would focus more on the app itself than the distribution platform. However I do agree, that it is equally important to promote the distribution platform itself as well.
    • After first launch, is there an ability for the user to change update settings? (For instance, on first launch he wanted only fixes, but on next one wants minor updates and so on)
  3. Missing parts of documentation

    • I was missing some crucial part of the information. That’s how I found myself digging through the code.
    • There is no info, where information is stored. For instance, where is the downloaded JRE’s and downloaded app archives? Now I know it is stored in ~/.jdeploy/..
  4. Uninstall

    • How do you uninstall the app? On windows there is an uninstaller.

      But mac system has a different design. When you’re using a regular app install, you just delete the app icon from applications, that is it. However, with this installer, it would leave JRE’s and app jar files inside user home directory.

      This is really a big problem. I have an app that my users are using at least 2-3 years now. App jar weights around 50mbs. So after a year or so, it really would be a memory problem, when there is software parts that are not used any more.

  5. Different JRE’s

    • Right now launcher uses official JRE’s. This has few side effects.
      • When bundling project with jlink, it would strip out unneeded parts of JRE. If the app is small, this significantly uses less ram and launch speed is increased. Using full JRE, it would always launch an full fledged JRE into memory.
      • If there’s a need for some reason to use older version of JFX, JRE.

So these are my initial thoughts about the project.

Don’t get me wrong, I love the idea and the project seems that is really address crucial concerns of java desktop. I would love to see this project bloom into something truly spectacular.

Cheers!

marius-m avatar Apr 03 '22 08:04 marius-m

Project uses libraries in jars instead of maven repo

Which libraries are you referring to? jDeploy uses Maven for dependencies.

Project uses other projects from repositories copied over instead of a submodule

I used AppBundler as a starting point when I began this journey. If you do a diff you'll find that the remnants of it that remain in jDeploy are changed drastically. Many parts have been removed, added, and rewritten to support the goals of jDeploy. I wouldn't consider it to be a dependency of jDeploy anymore.

Change splash screen with custom images that would focus more on the app itself than the distribution platform.

You're probably referring to the installer splash screen, as the app splash screen will use the app name and icon. Originally this was a limitation because all apps use the same installer (for codesign reasons) but download app metadata using a code in the installer name. Recently I made some changes to the launcher, however, that could allow for some splash screen customization. I have added this as an issue.

I don’t understand empty lines in code and when should use it?

I'm indifferent to whitespace. There is no significance to those whitespace sections other than that probably there used to be something there that has been removed. If you don't like the whitespace, feel free to submit a PR that removes it, and I'll gladly accept it.

It seems to me that there is no way to distribute (at least documentation does not state it so) only on NPM and ignore uploading to jdeploy.com/~app ?

When you deploy your app with jDeploy, it uploads the app to npm. The download page on jDeploy doesn't actually deal with your app directly. It just bundles up an installer for your app, which is the generic jDeploy installer and some minimal metadata for your app, which it gets from npm. The jdeploy "publish" command, does, however upload your app's icon, and installer artwork to jdeploy.com so that the installer is able to get that information. This is necessary because all apps use the same installer, which is signed and notarized. This could be avoided if you were to sign your own installer.

Documentation how to set-up using a custom repository, where app could be downloaded.

In my first iterations, jDeploy supported self-hosting, but after I incorporated npm, I decided to "turn off" that functionality to focus on the npm pathway because it was much simpler. People have expressed interest in self-hosting (on HackerNews discussions, and Reddit, etc...), but nobody has yet approached me with a full, coherent use case. I suspect that such a feature would need to be bundled with other privacy-related features, such as support for signing your own installer.

Once we delve into that territory (signing your own installer, using your own private npm repo), I think it is worth looking at the problem fresh to ensure that we're not solving half a problem, and building something that nobody needs. I have gone to great pains to refine the deployment and install workflow for jDeploy to satisfy my own distribution issues. I think that the same considering will be required for a private repo feature. For the distribution process, there are lots of tools that could be used - github actions, jpackage, etc... For the installation process, there also many options - custom installer, DMG, pkg, etc... For the update process, there may also be additional considerations.

Probably this one needs to be its own issue too. The starting place for determining what the MVP looks like is to ask the question "why do you want a private repo?". Some other requirements will probably fall out of the answer.

After first launch, is there an ability for the user to change update settings? (For instance, on first launch he wanted only fixes, but on next one wants minor updates and so on)

Currently, they just need to run the installer again. I'm open to suggestions on better solutions.

For instance, where is the downloaded JRE’s and downloaded app archives? Now I know it is stored in ~/.jdeploy/..

I've added an issue for this https://github.com/shannah/jdeploy/issues/49

How do you uninstall the app? On windows there is an uninstaller.

More work needs to be put into uninstallers. One thing to note is that, on mac at least, you can nuke the entire ~/.jdeploy directory and your app will still work fine. It will just recreate it and download what it needs on the next launch. On windows and linux it stores the apps in the ~/.jdeploy/apps directory, so you can't nuke the whole ~/.jdeploy and have the apps still work, but you can nuke everything except the ~/.jdeploy/apps directory.

The Windows uninstaller was created to mop up registry entries that it adds in the installer. A similar uninstaller should be written for linux, but I haven't done it yet.

This feature sounds like something that could/should be added to the installer itself - perhaps an "Advanced" menu that allows the user to "delete old versions". I've added an issue for this also. https://github.com/shannah/jdeploy/issues/50

When bundling project with jlink, it would strip out unneeded parts of JRE. If the app is small, this significantly uses less ram and launch speed is increased. Using full JRE, it would always launch an full fledged JRE into memory.

I can look into incorporating jlink but it makes things much more complicated, and I'm not sure how much is gained. Do you have any data on the memory differences between running the same app in a full JRE vs a stripped-down JRE with jlink. (I'm not talking about graal native image - just jlink).

If there’s a need for some reason to use older version of JFX, JRE.

For the JRE you can target a major version. E.g. 8, 11, 17. So you can use an old version. You can't target a specific minor version, or bundle your own JRE right now. This seems like a pretty niche requirement. For the "old versions of JFX", that is possible if you keep the "JavaFX" option unchecked in your jDeploy settings for the app, then bundle the JavaFX jars with your app. This isn't great, however, since you need to bundle all platforms which increases app size. I have toyed with tapping into Maven to download dependencies dynamically at install time. This would largely solve that problem. However, there is a lot to consider here - namely whether to just use Maven directly, or to create my own custom dependencies system. Maven may be overkill, and using it in this context may present more problems than it solves.

Thanks for the feedback.

shannah avatar Apr 03 '22 12:04 shannah

Thank you for a swift reply! The answers were really helpful insights. I’m try out and bundle the app with limited users to see if everything works. As far as I’ve tried on different computers, the tools is really useful!

Libraries

- Project uses libraries in jars instead of maven repo
Which libraries are you referring to? jDeploy uses Maven for dependencies.

I was referring to rootDir/lib folder, which had *jar files. However, probably I’ve just noticed them, didn’t delve futher 🤷‍️ how the libraries were used.

Whitespace

- I don’t understand empty lines in code and when should use it?
I'm indifferent to whitespace. There is no significance to those whitespace sections other than that probably there used to be something there that has been removed. If you don't like the whitespace, feel free to submit a PR that removes it, and I'll gladly accept it.

No I’m not really zealous about the whitespace or anything, I was just thinking if I should follow any rules around the topic if I would prefer contributing to the repository itself.

Uninstallers

I think I’ll have to put a bit of thought how to do a clean-up. Maybe putting “clean” function inside the installer itself would be useful 🤔

Custom JRE

I haven’t measured it, but when launching JRE, it really “chews” quite a bit of ram for a simple app. I need to try out modularizing the app, maybe that would launch only needed parts.

marius-m avatar Apr 03 '22 12:04 marius-m

I was referring to rootDir/lib folder, which had *jar files. However, probably I’ve just noticed them, didn’t delve futher 🤷‍️ how the libraries were used.

Most of those can probably be safely removed. The project started out on ANT, but I migrated to Maven at some point. In some cases I couldn't find Maven equivalents, so I kept jars around, but at this point I think most/all of the deps have been converted to Maven dependencies. I need to go through each one to make sure before stripping them out.

shannah avatar Apr 03 '22 13:04 shannah