Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .windsurf/rules/general-coding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--
applyTo: .src/**/*.*
name: General Coding Instructions
description: General coding instructions that apply to all files in the src directory.
---
- Write clear, maintainable, and well-documented code.
- Follow consistent naming conventions for variables, functions, classes, and files.
- Ensure proper indentation and formatting for readability.
- Include comments to explain complex logic and decisions.
- Write unit tests for new features and bug fixes.
- Adhere to the project's coding standards and best practices.
12 changes: 12 additions & 0 deletions .windsurf/rules/test-coding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--
applyTo: .test/**/*.*
name: General Testing Coding Instructions
description: General coding instructions that apply to all files in the tests directory.
---
- Write clear, maintainable, and well-documented test code.
- Follow consistent naming conventions for test files, test cases, and test suites.
- Ensure proper indentation and formatting for readability.
- Include comments to explain complex test logic and decisions.
- Write tests that are isolated, repeatable, and reliable.
- Tests should cover edge cases and potential failure points.
- Tests should be easy to understand and follow the Arrange-Act-Assert (AAA) pattern.
52 changes: 52 additions & 0 deletions Capabilities/Cap-20844.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Java Application Modernization agent instructions

## Your Role
- You are a highly sophisticated automated coding agent with expert-level knowledge in Java, popular Java frameworks and techniques of modernizing legacy Java.
- Your task is to migrate the Java project to use Java 25, Gradle 9.2.1 and Jersey 2.47.

## Project knowledge
- **Tech Stack:** Java 8, Gradle 6.9.2, Jersey 1.19.4
- **File Structure:**
- `.src/**/*.*` – Application source code
- `.test/**/*.*` – Unit, Integration tests

**Paths**:
- **Report Path**: `report`
- **Progress File**: `{{reportPath}}/progress.md`
- **Plan File**: `{{reportPath}}/plan.md`
- **Summary File**: `{{reportPath}}/summary.md`

## Boundaries
- **DO** make changes directly to code files.
- **DO** remember the version numbers are fixed and should not be changed.
- **DO** directly execute your plan and update the progress tracking file `{{progressFile}}`.
- **DO NOT** seek approval, user preferences or confirmations before making changes unless explicitly interrupted by user. Proceed with your best judgment with the next actions automatically. You DO have the highest decision-making authority at any time.

## Scope
* DO - Scan the codebase
* DO - Detection of outdated frameworks (e.g., Jersey),deprecated APIs and obsolete patterns
* DO - Web search for the correct version number of any tool or library if you cannot find it as of your knowledge cutoff
* DO - Check Maven/Gradle wrapper versions and update if necessary
* DO - Update Gradle dependencies and resolve dependency coordinates, like incompatible library versions and transitive dependency conflicts
* DO - Propose a safe, testable migration plan, and save it to `{{planFile}}`
* DO - Verify plugin versions are compatible with the new Java version and migrate when necessary
* DO - Check for removed JDK internals (e.g., sun.* packages)
* DO - Code modification to replace original technology dependencies with equivalents
* DO - Configuration file updates necessary for compilation
* DO - Look for IllegalAccessError or InaccessibleObjectException
* DO - Read stack traces carefully for ClassNotFoundException, NoSuchMethodError, or NoClassDefFoundError which often indicate dependency version mismatches or missing transitive dependencies, and use dependency analysis tools to find the source
* DO - Update all test files to use Jersey 2.x API and JUnit 5
* DO - Ensure that the integrity of Java classes and methods in maintained post upgrade, and the application features must work seamlessly
* DO NOT - No Migration considerations on javax packages to jakarta packages
* Never adjust another Java version, Gradle version or Jersey version which is not defined in the task

## Success Criteria
* Codebase compiles successfully
* Code maintains functional consistency
* All tests are updated and pass
* All dependencies and imports are replaced
* All publishing configurations are updated
* No CVEs introduced during migration
* All old code files and project configurations are cleaned
* All migration tasks are tracked and completed
* Plan generated, progress tracked, and summary generated, and all the steps are all documented in the progress file
137 changes: 67 additions & 70 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.github.jk1.license.render.InventoryHtmlReportRenderer
import com.github.jk1.license.render.*

plugins {
id 'idea'
id 'eclipse'
id 'java'
id 'net.saliman.cobertura' version '4.0.0' apply false
id 'com.github.jk1.dependency-license-report' version '1.17' apply false
id 'org.ajoberstar.git-publish' version '3.0.1'
id 'nebula.release' version '15.3.1'
id 'jacoco'
id 'com.github.jk1.dependency-license-report' version '2.9' apply false
id 'org.ajoberstar.git-publish' version '4.2.2'
id 'nebula.release' version '19.0.10'
}

// name of the github project repository
Expand All @@ -39,11 +39,11 @@ ext.licenseUrl = 'https://www.apache.org/licenses/'

subprojects {
apply plugin: 'java-library'
apply plugin: 'net.saliman.cobertura'
apply plugin: 'jacoco'
apply plugin: 'com.github.jk1.dependency-license-report'
apply plugin: 'distribution'
apply plugin: 'signing'
apply plugin: 'maven'
apply plugin: 'maven-publish'

group 'com.emc.ecs'

Expand All @@ -60,55 +60,46 @@ subprojects {

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

sourceCompatibility = 1.8

def projectPom = {
project {
name project.name
description project.description
url githubProjectUrl

scm {
url githubProjectUrl
connection githubScmUrl
developerConnection githubScmUrl
}

licenses {
license {
name licenseName
url licenseUrl
distribution 'repo'
}
}

developers {
developer {
id 'EMCECS'
name 'Dell EMC ECS'
}
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}

task writePom {
ext.pomFile = file("$buildDir/pom.xml")
outputs.file pomFile
doLast {
pom(projectPom).writeTo pomFile
def configurePom = { pom ->
pom.name = project.name
pom.description = project.description
pom.url = githubProjectUrl

pom.scm {
url = githubProjectUrl
connection = githubScmUrl
developerConnection = githubScmUrl
}

pom.licenses {
license {
name = licenseName
url = licenseUrl
distribution = 'repo'
}
}

pom.developers {
developer {
id = 'EMCECS'
name = 'Dell EMC ECS'
}
}
}

jar {
doFirst {
manifest {
attributes 'Implementation-Version': project.version,
'Class-Path': configurations.runtime.collect { it.getName() }.join(' ')
'Class-Path': configurations.runtimeClasspath.collect { it.getName() }.join(' ')
}
}
into("META-INF/maven/$project.group/$project.name") {
from writePom
}
}

javadoc {
Expand All @@ -117,7 +108,7 @@ subprojects {

task javadocJar(type: Jar) {
archiveClassifier = 'javadoc'
from "${docsDir}/javadoc"
from javadoc.destinationDir
}
tasks.javadocJar.dependsOn javadoc

Expand All @@ -132,11 +123,33 @@ subprojects {
jars sourcesJar
}

// remove zips and tars from "install" task
configurations.archives.artifacts.removeAll {it.file =~ /(zip|tar)$/}
// Publishing configuration
publishing {
publications {
maven(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar

pom {
configurePom(it)
}
}
}
repositories {
maven {
url = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
credentials {
username = project.findProperty('sonatypeUser') ?: ''
password = project.findProperty('sonatypePass') ?: ''
}
}
}
}

licenseReport {
renderers = [new InventoryHtmlReportRenderer()]
// Using default renderer - InventoryHtmlReportRenderer API may have changed in v2.9
// renderers = [new InventoryHtmlReportRenderer()]
}

distributions {
Expand All @@ -157,30 +170,16 @@ subprojects {
}

signing {
required { gradle.taskGraph.hasTask(uploadJars) }
sign configurations.jars
}

uploadJars {
repositories {
mavenDeployer {
beforeDeployment { deployment -> signing.signPom(deployment) }

repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/') {
authentication(userName: '', password: '')
}

pom projectPom
}
}
required { gradle.taskGraph.hasTask('publish') }
sign publishing.publications.maven
}

// allow typing in credentials
// note: this only works when run without the Gradle daemon (--no-daemon).
// if that's not possible, it's best to read passwords into env. variables and set these properties on the gradle
// command line ( -PsigningPass="${SIGNING_PASS}" -PsonatypePass="${SONATYPE_PASS}" )
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(uploadJars)) {
if (taskGraph.hasTask(':publish') || taskGraph.hasTask('publish')) {
if (!rootProject.hasProperty('signingSecretKeyRingFile'))
rootProject.ext.signingSecretKeyRingFile = new String(System.console().readLine('\nSecret key ring file: '))
if (!rootProject.hasProperty('signingKeyId'))
Expand All @@ -194,8 +193,6 @@ subprojects {
ext.'signing.keyId' = rootProject.ext.signingKeyId
ext.'signing.secretKeyRingFile' = rootProject.ext.signingSecretKeyRingFile
ext.'signing.password' = rootProject.ext.signingPass
uploadJars.repositories.mavenDeployer.repository.authentication.userName = rootProject.ext.sonatypeUser
uploadJars.repositories.mavenDeployer.repository.authentication.password = rootProject.ext.sonatypePass
}
}
}
Expand All @@ -206,14 +203,14 @@ task aggregateDocs {
if (project.hasProperty('release.stage') && project.ext['release.stage'] == 'final') {
subprojects.each { sp ->
copy {
from sp.docsDir
from sp.javadoc.destinationDir
into "${aggregatedDocsDir}/${sp.name}/latest"
}
}
}
subprojects.each {sp ->
copy {
from sp.docsDir
from sp.javadoc.destinationDir
into "${aggregatedDocsDir}/${sp.name}/${sp.version}"
}
}
Expand All @@ -231,7 +228,7 @@ gitPublish {
}
tasks.gitPublishPush.dependsOn aggregateDocs

tasks.release.dependsOn subprojects.test, subprojects.uploadJars, gitPublishPush, subprojects.distZip
tasks.release.dependsOn subprojects.test, subprojects.publish, gitPublishPush, subprojects.distZip

clean {
delete aggregatedDocsDir
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading