cuba-platform / cuba-gradle-plugin

Gradle plugin for building CUBA platform and applications
https://www.cuba-platform.com
Apache License 2.0
15 stars 18 forks source link

Dependencies of uberJar type must be declared only on top level #126

Closed belyaev-andrey closed 4 years ago

belyaev-andrey commented 4 years ago

Environment

Description of the bug or enhancement

Case: I need to add a 3rd-party appender to the logstash. I use the following in my logback configuration file for both uberJar and WAR deploy:

    <appender name="Logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>logstash:4560</destination>
        <!-- encoder is required -->
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

I need to add a dependency to my project:

configure(globalModule) {
    dependencies {
        uberJar ('net.logstash.logback:logstash-logback-encoder:6.3')
        if (!JavaVersion.current().isJava8()) {
            runtime('javax.xml.bind:jaxb-api:2.3.1')
            runtime('org.glassfish.jaxb:jaxb-runtime:2.3.1')
        }
    }
}

It works fine if I use WAR deployment scheme, logs are being set to the logstash host.

But for the UberJar it doesn't work, because logback starts BEFORE the application is started, therefore in UberJar I got an error:

Caused by: java.lang.ClassNotFoundException: net.logstash.logback.appender.LogstashTcpSocketAppender
        at      at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
        at      at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
        at      at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
        at      at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:56)                                                 at      ... 34 common frames omitted

This can be resolved by adding the dependency as uberJar, not runtime.

The problem can be solved if the dependency is declared at top level:

dependencies {
    appComponent("com.haulmont.cuba:cuba-global:$cubaVersion")
    uberJar ('net.logstash.logback:logstash-logback-encoder:6.3')
}

But in this case, the library is not packed to WAR files and I got the error:

Caused by: java.lang.ClassNotFoundException: net.logstash.logback.appender.LogstashTcpSocketAppender
        at      at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365)
        at      at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
        at      at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:56)
        at      ... 63 common frames omitted

If the dependency is declared at both places (top level and global module), it is packed twice to the uberJar.

belyaev-andrey commented 4 years ago

Sample project: logstashtest.zip

soraksh commented 4 years ago

It was decided to add server dependency type to modules. If dependency added as server to core, web or portal modules (modules that have task with type CubaDeployment) it will be placed to server libs by deploy, buildWar and buildUberJar tasks.

MikhailSilk commented 4 years ago

Case 1

  1. Add server to the core module in the build.gradle file
  2. Build UberJar
  3. Open generated web module (for example app.jar)
  4. Check that folder with server libs not created

AR: Server libs were added to the web module. Also, server libs add in the portal module if it was added to the project.

Case 2

  1. Create a new project
  2. Create the first entity
  3. Install app component to the local maven repository
  4. Create the second entity and delete the first entity
  5. Undeploy project
  6. Change the artifact version
  7. Install app component to the local maven repository
  8. Create a new project
  9. Select Use Local Maven repository property in the Project properties
  10. Add the first artifact coordinates of the previous project as server to the core module
  11. Add the second artifact coordinates of the previous project as server to the web module
  12. Build the single UberJar

AR: Server libs for the first artifact coordinate and the second artifact coordinates were added to the one folder

MikhailSilk commented 4 years ago

Checked: