Add runtime classpath folder to custom gradle plugin


(Sanket Sharma) #1

Hi,

I have a project that uses a custom proprietary format to build and deploy solutions (its a third party application that we’re using). The vendor did provide eclipse RCP based Ant tasks that I was able to link with Gradle and build process works fine.

However, as the last step in the build process, the task tries to connect to vendor’s repository using settings in a properties file. In normal situations when running their utilities or programs from command line/Eclipse, the recommended way is to add the folder containing the properties file to the classpath. They do not have an API where you can specify the location of the properties file and load it directly.

I am slightly lost as how to achieve this using Gradle. From reading documentation and searching through forms, it seems that the plugin itself cannot modify the classpath. So that is ruled out.

I tried adding the folder (and even the file) to dependencies using compile and rutime files() option but it didnt help. I tried to add the folder to buildscript dependencies section, but that didnt help’ either.

I am considering a few options, but would like to get some advice from the experts as to what is the best/recommended way:

  1. I can potentially deploy the properties file as jar and let gradle resolve the dependency. The downside is (maybe not) that we’ll have to maintain different versions of jars across different environments as settings are environment specific.

  2. Use a filter mechanism to bundle an environment specific jar with the project when it is built for each environment.

  3. Somehow figure out a way to set classpath for the plugin/script while its executing that task either via command line options/environment variables etc. The upside is, very little config/code.

What do you guys recommend? What is the best way?

Sanket


(Peter Niederwieser) #2

If you declare the folder as a regular dependency (in the ‘project.dependencies’ block), the Ant tasks won’t see it. I think that adding the folder as a buildscript dependency should work, although I’m not 100% sure. I don’t have any other ideas how to make this work, except for double-checking that you got the buildscript dependency declaration right.


(Sanket Sharma) #3

Hey Peter,

Thank you for the response. Sorry, I should have supplied more details. So, in my custom plugin, I have the following tasks:

  1. ImportProject ->Calls the ant task using javaexec/eclipse rcp. Works fine. 2. BuildAndPackageProject -> Calls the ant task using javaexec/eclipse rcp. Works fine. 3. DeployProject ->Calls the ant task using javaexec/eclipse rcp. Works fine. 4. TestProject -> Runs TestNG tests with customized resource paths. Regular Gradle/Java plugin (No Ant) Works fine. 5. RunCustomScript -> This task in the custom plugin runs the code that looks for the properties file. It is not an Ant task, plain java code in the plugin that tries to look up the properties file on classpath.

I will upload the snippets shortly.


(Peter Niederwieser) #4

Is that your own custom plugin? In that case, the natural solution is to make the properties file a regular resource of the plugin.


(Sanket Sharma) #5

Yes, that is my own plugin.

I thought about that option, but the properties file contain environment settings, so there is a property file per environment e.g. one for dev, one for test, one for pre-production and one for production (Basically connection settings to a repository)

If I include it as a resource, that will probably work. but then I’ll have to either to build the plugin once for each environment or else, package the jar and publish it our local maven/ivy repository. Since it contains passwords (although encrypted) I wonder if that would be great idea…

That would also mean having two properties file on the same machine - one installed by gradle/maven/ivy and other by the application.

If there’s no other way…I can potentially launch a javaexec again and customize the startup classpath?

I tried to dump all classpath entries from the plugin and it seems no matter what I specify, the only classpath entry that gets passed to the plugin is gradles’s own ?


(Peter Niederwieser) #6

Sounds like the way that the third-party code is dealing with properties files is limiting your options here. ‘javaexec’ may be the easiest solution. Having your plugin deal with its own class loader might be another option.


(Sanket Sharma) #7

Yeah. I would have at least expected a method where you could specify the location of the file (much like log4j or perhaps even construct settings/connection object programmatically.

Do you think changing the class loader might help? Something like:

new URLClassLoader(folderLocation)

and then setting this as the classloader for current thread?

Not at my machine at the moment but will give it a try tomorrow morning…


(Peter Niederwieser) #8

It depends on how the code acquires the class loader used to load the properties file. There are several potential ways to solve the problem with a plugin-managed class loader, but first I’d check if a ‘javaexec’ based solution is good enough.


(Sanket Sharma) #9

Thanks Peter. I’d give it a shot tomorrow and post my results here. Thank you once again for the quick responses.