Struts2-core 7.0.3 migration

Hello,

I am very new to Gradle and loving it so far.
Any guidance would be greatly appreciated.

Using Intellij, Open Liberty, Gradle
I am able to get struts2-core:2.5.33 working , but when I change the
Implementation to struts2-core:7.0.3, I received this error:

org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter was found, but is missing another class

//My build.gradle:

apply plugin: 'war'
apply plugin: 'liberty'

sourceCompatibility = 21
targetCompatibility = 21
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

// configure liberty-gradle-plugin
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'io.openliberty.tools:liberty-gradle-plugin:3.9.3'
    }
}

repositories {
    mavenCentral()
}

dependencies {
    // provided dependencies

   providedCompile 'jakarta.platform:jakarta.jakartaee-api:10.0.0'
    providedCompile 'org.eclipse.microprofile:microprofile:7.0'

    implementation("org.apache.struts:struts2-core:7.0.3")
    implementation 'javax.servlet:javax.servlet-api:4.0.1'
    implementation 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'
    implementation 'org.slf4j:slf4j-api:2.0.12'
    implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.23.1'
    implementation("com.opensymphony:xwork:2.1.3")

    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'

    providedCompile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.1'



    // test dependencies
    testImplementation 'junit:junit:4.13.2'
    testImplementation platform('org.junit:junit-bom:5.13.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'org.apache.httpcomponents.client5:httpclient5:5.5'

}

ext  {
    liberty.server.var.'http.port' = '9080'
    liberty.server.var.'https.port' = '9443'
    liberty.server.var.'app.context.root' = project.name
}

task openBrowser {
    description = 'Open browser to the running application'
    doLast {
        String port = liberty.server.var.'http.port'
        String context = liberty.server.var.'app.context.root'
        String URL = "http://localhost:" + port + "/" + context + "/" + "servlet + \"/\" + index.action"
        java.awt.Desktop.desktop.browse URL.toURI()
    }
}

test {
    useJUnitPlatform()
    testLogging {
        events 'passed', 'skipped', 'failed', 'standardOut'
        exceptionFormat 'full'
    }
    systemProperty 'http.port', liberty.server.var.'http.port'
    systemProperty 'context.root',  liberty.server.var.'app.context.root'
}

test.dependsOn 'libertyStart'
test.finalizedBy(openBrowser)
clean.dependsOn 'libertyStop'

Hi there, glad that you like Gradle. :slight_smile:

Some comments from a cursory look if you mind:

  • I strongly recommend you switch to Kotlin DSL. By not it is the default DSL, you immediately get type-safe build scripts, actually helpful error messages if you mess up the syntax, and amazingly better IDE support if you use a good IDE like IntelliJ IDEA or Android Studio
  • Do not use the legacy way to apply plugins by adding them in buildscript block and using apply ..., if that is how “liberty” (whatever that is) documents it, report a documentation bug. That is the discouraged legacy way of applying plugins and you should practically always prefer to apply plugins in the plugins { ... } block instead which also adds them to the classpath automatically if necessary. You should usually never need to use a buildscript { ... } block nowadays, especially not to just use some plugin.
  • Consider using JVM Toolchains feature to decouple the version you run Gradle with from the version you compile and run your code with instead of relying on using Java 21+ to run Gradle and setting the compatibility values.
  • Do not use ext / extra properties, they are practically always a work-around for not doing something properly. Actually in your case you do not even use extra properties, you just wrapped those three lines totally unnecessarily into the ext { ... } block where they don’t belong. You just set three properties in the var properties field of the server extension on the liberty extension, you can just move those out, or write them more DSL-y like a liberty block that contains a server block that contains var.'...' = ... lines.
  • Using explicit dependsOn where on the left-hand side is not a lifecycle task is practically always a code-smell. In most cases it means that you do not have task outputs properly wired to task inputs which comes with the necessary task dependencies implicitly. In your case though it means that you are using the wrong facility. To start a server for tests and shut it down afterwards, the proper way is a shared build service. That is one of its main use-cases actually. For example how you have it now, you keep the server running and only stop it if you run libertyStop or clean which you should almost never run, because you destroy one of the biggest strengths Gradle has, avoiding unnecessary work. You also always start the server if the test task is in the task graph, even if the test task is up-to-date or getting taken from the build cache.

Regarding your actual question, you forgot to share the concrete error you are getting.
From a vague description what kind of error you see it is extremely hard to impossible to give any meaningful and helpful comment. _:slight_smile: