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

Reduce assumptions about project structure #48

Closed
alexanderfloh opened this issue Jan 17, 2017 · 12 comments
Closed

Reduce assumptions about project structure #48

alexanderfloh opened this issue Jan 17, 2017 · 12 comments
Assignees
Labels
enhancement is:fixed This issue is fixed but not yet published issuer feedback More information or feedback is needed from the issuer

Comments

@alexanderfloh
Copy link

alexanderfloh commented Jan 17, 2017

Hi, I've already added this as comment to #37 but I think it may have been lost.

Unfortunately I'm still unable to build my application, so I'll try to give more context.
As mentioned before, the application consists of multiple modules, and the distribution should look like this (items marked with a * should go in the classpath):

outputDir
| application.exe
+ \ module A
  + \ moduleA.jar *
    + \ lib (native .DLLs go here)
    + \ config *
    | <arbitrary other files>
+ \ module B
  + \ moduleB.jar *
    /* ... */
+ \ <third party libs> *

Ideally, I'd like to be able to convince the launch4j plugin to not make any assumptions about my directory structure. Just point it at a directory, specify what should be included in the classpath and have it generate an .exe-file.

Alternatively, being able to provide a CopySpec for copyConfigurable might work as well for me, but I'm a bit worried about that resulting in an unnecessary amount of copies of the output files.

Thanks for investing your time in this, I appreciate it.

@TheBoegl TheBoegl self-assigned this Jan 17, 2017
@TheBoegl
Copy link
Owner

Should the config within the moduleA go into the classpath or is that a typo?

@alexanderfloh
Copy link
Author

That is correct.
Some libraries like their config files in the classpath, I guess because it makes it easy to look it up.

@TheBoegl
Copy link
Owner

Could you please create a test repo with the subprojects/modules and some of these libraries? That would really help here.

@alexanderfloh
Copy link
Author

I've created a simple project a https://github.com/alexanderfloh/launch4j-issue48 to show the basic structure. However, I ran into the problem that the files specified in copyConfigurable are copied to the lib folder, but apparently do not end up in launch4j.xml's classpath (noticed that when the generation failed once and the config file was not deleted, as well as launching the .exe with --l4j-debug-all).

Also, as mentioned above there is no way of retaining the folder structure.
I'd like it to result in

lib/launch4j-issue48.exe
lib/module-a/module-a.jar
lib/module-a/config
lib/module-b/module-b.jar

@gravelld
Copy link

gravelld commented Jan 20, 2017

As per #49 I would like a way of specifying no classpath, so just the JAR file specified in the jar parameter is used to start the application. Something like:

copyConfigurable=[]

But when I do this, I still have all the dependent JARs for the current project added to the classpath (from --l4j-debug):

Add classpath:	lib\guice-4.1.0.jar
Add classpath:	lib\scala-guice_2.11-4.1.0.jar
...

I took a look at CopyLibraries and realised:

            if (copyConfigurable) {
                with {
                    from { copyConfigurable }
                }

https://github.com/TheBoegl/gradle-launch4j/blob/develop/src/main/groovy/edu/sc/seis/launch4j/CopyLibraries.groovy#L41

I guess this is why copyConfigurable=[] doesn't work - because it evaluates to false?

A-ha - another workaround. I realised my project uses the application plugin, which makes it a Java project, thus the compile dependencies are included on the classpath.

I didn't need that, changed to distribution plugin only, and this appears to work - the entire classpath is not copied in.

Apologies for the rambling, I hope this helps someone else.

TheBoegl added a commit that referenced this issue Jan 21, 2017
This commit allows to change the resulting library folder structure by setting the `copyConfigurable` with either a FileCollection or a CopySpec. The latter will result in an incomplete UP-To-DATE check on the second run after a change and so should only be used as last resort.
TheBoegl added a commit that referenced this issue Jan 21, 2017
This commit allows to change the resulting library folder structure by setting the `copyConfigurable` with either a FileCollection or a CopySpec. The latter will result in an incomplete UP-To-DATE check on the second run after a change and so should only be used as last resort.
@TheBoegl
Copy link
Owner

@gravelld copyConfigurable=[] should work now.

@alexanderfloh the commit c31e050 f99e3c5 should allow the following configuration:

def mySpec = copySpec {
    from(project(':module-A').jar.outputs.files) {
        into('module-a')
    }
    from(project(':module-A').sourceSets.config.resources) {
        into('module-a')
    }
    from(project(':module-B').jar.outputs.files) {
        into('module-b')
    }
}
 
launch4j {
  mainClassName = 'A'
  dontWrapJar = true
  headerType = 'console' // just for testing the printlns of your test project
  jar = "module-a.jar"
  copyConfigurable = mySpec
}

The resulting classpath section in the launch4j xml looks like:

<classPath>
  <mainClass>A</mainClass>
  <cp>lib\module-a\module-A.jar</cp>
  <cp>lib\module-a\someConfigFile.xml</cp>
  <cp>lib\module-b\module-B.jar</cp>
</classPath>

@alexanderfloh
Copy link
Author

@TheBoegl works fine for the demo project, I'll also try if for my real app.

Can you please clarify what you meant by

The latter will result in an incomplete UP-To-DATE check on the second run after a change

Again, thanks for all the work you're putting into this!

@TheBoegl
Copy link
Owner

TheBoegl commented Jan 23, 2017

You're welcome!

In the current implementation I've seen no other way how to configure the task inputs if a CopySpec is passed into the copyConfigurable. The from properties are retrieved correctly for the task inputs, but the into folder makes it difficult. I had to work around it, like I've done in the implementation, so a change of any into folder would trigger a new build. The offside of this is that the UP-TO-DATE check fails on the second run of the same configuration, which results in a rebuild of the executable.

If that is OK for you, please close this issue, otherwise feel free to help to improve this implementation.

@gravelld
Copy link

Thanks for your work @TheBoegl

@alexanderfloh
Copy link
Author

@TheBoegl I discovered another problem when trying it with my real world app:

I didn't realize that it makes a difference when adding directories to the classpath vs. adding files to the classpath.
I updated the demo project to incorporate the changes you've made, and now I'm getting
<cp>lib\module-a\config\someConfigFile.xml</cp> in the generated launch4j XML file, when I really want
<cp>lib\module-a\config</cp>, because only then the file will be placed on the classpath so the code can pick it up (see A.java to see what I mean).

I'm guessing that this resolving of the actual files rather than just using the directory is a side effect of using the CopySpec, and my guess it is required for the up-to-date checks, but I'm hoping you may have another idea how to solve this.

In the Gradle Eclipse plugin I've noticed they give you various levels of fallbacks to modifiy the generated Eclipse project's classpath do you think something like this might make sense here as well?

@TheBoegl
Copy link
Owner

IMHO I don't think that a CopySpec with a set into folder (relative file) should automatically go into the classpath because it might have difficult side effects though I might find a way around the current restriction.

Would it be OK for you to configure the classpath on your own and provide the CopySpec? This way the convention over configuration approach would work for a typical use case and a special one, like yours, would be configurable after all.

TheBoegl added a commit that referenced this issue Jan 28, 2017
This commit adds the option to override the classpath which usually is created by the runtime configuration or the `copyConfigurable`. This should only be used as last resort fall back option because no further internal configuration is used or the input validated.
@TheBoegl
Copy link
Owner

@alexanderfloh I've pushed the changes to OJO as version 2.4.0-SNAPSHOT. You can test this snapshot and give feedback afterwards.

@TheBoegl TheBoegl added is:fixed This issue is fixed but not yet published issuer feedback More information or feedback is needed from the issuer labels Jan 12, 2018
@TheBoegl TheBoegl closed this as completed Nov 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement is:fixed This issue is fixed but not yet published issuer feedback More information or feedback is needed from the issuer
Projects
None yet
Development

No branches or pull requests

3 participants