gradle javaexec error “’apiElements’ directly is not allowed”- Gradle 5.4.1

Tags: , ,



I am new to Gradle and trying to migrate an existing system build from ant to Gradle. As part of this I need to run a java program on every file in a directory. Directory contains xml files and the java code will parse and convert .xml to .java files (and these Java files would be build to generate class and package in final jar) after performing some business specific transformation.

below is a function I wrote in Gradle

private runJavaFile(String dirPath) {
    FileTree tree = fileTree(dir: dirPath, include: '**/*.xml')
    tree.each {
        def xmlfile = it.path
        def javaFile = it.path.replaceFirst(".xml", ".java")
        javaexec {  //// getting error on this line
            classpath configurations.all
            main = 'XmlToJavaParser'
            args = ["$xmlfile", "$javaFile", 'Java']
        }
    }
}

I am calling this function from a Gradle task by passing the dir path which contains the xml files to be parsed. While running the task, I am getting below error:

> Resolving configuration 'apiElements' directly is not allowed

Any help would be appreciated. Let me know if any more information is needed.

Answer

In Gradle, a configuration represents a group of artifacts and their dependencies. You typically have several configurations depending on what you want to do. For instance, you could have one where you declare which dependencies are needed for compilation, which are only needed at runtime, or which are needed for running a particular Java application.

In your case, you are saying that the classpath to the XmlToJavaParser class is “all configurations combined” and that doesn’t really make sense. You are also not allowed to do that as some configurations from the Java plugin are not resolvable like this, which is why you get an error.

So to fix it, you should declare your own configuration for XmlToJavaParser. You can then declare dependencies for it like you normally do. Example (using the Groovy DSL):

configurations {
    xmlJavaParser {
        canBeResolved = true
        canBeConsumed = false
    }
}

dependencies {
    xmlJavaParser "org.example:xml-java-parser:1.0" // or whatever you need
}

private runJavaFile(String dirPath) {
    // ...
    javaexec {
        classpath = configurations.xmlJavaParser // The configuration is referenced here
        main = 'XmlToJavaParser'
        args = ["$xmlfile", "$javaFile", 'Java']
    }
}

There are also other ways to go about it. But the main point is to not use configurations.all as a classpath.



Source: stackoverflow