Classpath in Application plugin is building always relative to %APP_HOME%/lib directory


(north_wind) #1

I have a little java project with standard directory set: ‘src/main/java’, ‘src/test/java’. I use Application plugin for make a distribution of the project and this distribution must have some configuration files, that lies IN classpath, but NOT in resources to give users an ability to change it.

Ok, for this feature I use ‘src/dist’ directory, from which all files copy to build/install/ (%APP_HOME%). I placed ‘config’ catalog to ‘src/dist’ and set ‘classpath’ of startScripts:

startScripts {
    classpath += files('src/dist/config')
}

Resulting directory is %APP_HOME%/config, but CLASSPATH in a launch script is %APP_HOME%/lib/config. Only function of scartScripts.classpath is configuring of launch script’s CLASSPATH and this function is not performed correctly.

It happens because of classpath calculating algorithm:

  1. ApplicationPlugin sets default classpath in the next way:
startScripts.classpath = project.tasks[JavaPlugin.JAR_TASK_NAME].outputs.files + project.configurations.runtime
  1. Then ‘…/task/application/CreateStartScript.groovy’ (that is used only from ApplicationPlugin.groovy) makes next step:
generator.classpath = getClasspath().collect { "lib/${it.name}" }

It configure resulting classpath and always add ‘lib/’.

I think it would be better to change a logic of classpath configuring: 1) ApplicationPlugin knows target pathes and build classpath fully itself. 2) ApplicationPlugin must build resulting classpath more smarty because it knows where to copy. 3) So, finally, in CreateStartScript.groovy

generator.classpath = getClasspath()

I think it’s not good that CreateStartScript makes some hidden work to final configure of classpath

If my way of thinking is right I can try to contribute to Groovy. Because my final scripts is look like this (it’s worked):

startScripts {
    classpath += files('src/dist/config')
      doLast {
        def windowsScriptFile = file getWindowsScript()
        def unixScriptFile
  = file getUnixScript()
          windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\lib\config', '%APP_HOME%\config')
        unixScriptFile.text
  = unixScriptFile.text.replace('$APP_HOME/lib/config', '$APP_HOME/config')
    }
}

Application plugin creates invalid classpath in start script
(Roger Searjeant) #2

Fadeev, Just wanted to thank you for this posting - I have had exactly the same problem and your explanation (and your work-around) have been extremely helpful. I am using your fixed-up startScripts task and it works perfectly.

I think this is a bug in Gradle and should be raised as a JIRA issue.


(Alexandr Fadeev) #3

You’re welcome :slight_smile: I wanted to fix this feature, but can’t build gradle because of another bug with proxy and other unpleasant things )) So, at this time this is the best solution…


(Fred Toth) #4

Hi,

I found your very useful post and I have the same problem. My question: Has there been any other activity on this issue. It looks like there’s a related JIRA ticket:

http://issues.gradle.org/browse/GRADLE-2333

But this is from June of 2012 and there’s been no activity. Does anyone know of a more recent ticket or more recent discussion?

Thanks,

Fred


Adding wildcard classpath entry in launch script
(Luke Daley) #5

I’ve raised GRADLE-2991 for this general problem.

A simpler solution is to actually copy the files into lib…

startScripts {
    classpath += files('src/dist/config')
}
application.applicationDistribution.into("lib") { from "src/dist/config" }

(Jordan Grant) #6

Similar to Luke’s suggestion, if you need to have configuration files in their own directory for whatever reason, you can still put them in their own directory under src/dist/lib (e.g. src/dist/lib/conf. Then the following snippet will work as expected:

startScripts {
    classpath += files('src/dist/lib/conf')
}