Skip to content

Commit e52ac84

Browse files
alpslaclaude
andcommitted
rex(#5): Fix JDepend to use source-based analysis when no compiled classes
Session 93: When no compiled .class files are found, JDepend now falls back to source-based analysis from architecture-runner.ts instead of returning empty results. Changes: - Modified runJDepend() in java-tool-orchestrator.ts - Uses javaArchitectureRunner.runSourceBasedAnalysis() as fallback - Converts architecture issues to RawIssue format - Detects: circular-dependency, god-package, high-efferent-coupling Tested on spring-petclinic (no compiled classes): - Found 4 high-efferent-coupling issues from source analysis Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 077b17c commit e52ac84

6 files changed

Lines changed: 207 additions & 711 deletions

packages/agents/src/two-branch/tools/java/java-tool-orchestrator.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -793,15 +793,33 @@ export class JavaToolOrchestrator extends BaseToolOrchestrator {
793793
const classesDir = await this.findJavaClassesDir(repoPath);
794794

795795
if (!classesDir) {
796-
logger.warn('⚠️ No compiled Java classes found. JDepend requires compiled .class files.');
797-
logger.warn(' Run: mvn compile (Maven) or gradle build (Gradle) first.');
796+
logger.info('🔄 No compiled Java classes found. Falling back to source-based analysis...');
797+
798+
// Session 93 Fix: Use source-based analysis from architecture-runner when no compiled classes
799+
const { javaArchitectureRunner } = await import('./architecture-runner');
800+
const sourceAnalysisIssues = await javaArchitectureRunner.runSourceBasedAnalysis(repoPath);
801+
802+
// Convert architecture issues to RawIssue format
803+
const issues: RawIssue[] = sourceAnalysisIssues.map(issue => ({
804+
tool: 'jdepend',
805+
file: issue.file || issue.packageName || '',
806+
line: issue.line || 0,
807+
column: 0,
808+
severity: issue.severity,
809+
message: issue.message,
810+
rule: issue.rule,
811+
category: 'architecture'
812+
}));
813+
814+
logger.info(`✅ Source-based analysis found ${issues.length} architecture issues`);
815+
798816
return {
799817
tool: 'jdepend',
800818
success: true,
801819
duration: Date.now() - startTime,
802-
issues: [],
803-
rawOutput: 'No compiled classes found. JDepend requires compiled .class files.',
804-
metadata: this.calculateMetadata([])
820+
issues,
821+
rawOutput: `Source-based analysis (no compiled classes): Found ${issues.length} issues`,
822+
metadata: this.calculateMetadata(issues)
805823
};
806824
}
807825

packages/agents/tests/integration/test-outputs/attachments/group-java-lang-security-audit-active-debug-code-printstacktrace-active-debug-code-printstacktrace-medium-semgrep-fix.json

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,30 @@
44
"rule": "java.lang.security.audit.active-debug-code-printstacktrace.active-debug-code-printstacktrace",
55
"tool": "semgrep",
66
"severity": "medium",
7-
"description": "Remove or conditionally disable debug print statements in production builds. Use a proper logging framework with appropriate log levels and ensure debug-level logging is disabled in production environments. Consider using build profiles or environment variables to control debug output.",
7+
"description": "Possible active debug code detected. Deploying an application with debug code can create unintended entry points or expose sensitive information.",
88
"fix_pattern": {
99
"type": "template",
10+
"fixTier": 2,
11+
"fixerTool": "ai",
12+
"fixerCommand": "ai",
13+
"confidence": 85,
1014
"example": {
1115
"before": "",
12-
"after": "public class MavenWrapperDownloader {\n // ... other code\n public static void main(String[] args) {\n // Remove or comment out debug logging\n // System.out.println(\"Downloading from: \" + MAVEN_WRAPPER_URL);\n // ... rest of the method\n }\n}"
16+
"after": "@GwtIncompatible // java.io.PrintWriter, java.io.StringWriter\n public static String getStackTraceAsString(Throwable throwable) {\n StringWriter stringWriter = new StringWriter();\n PrintWriter printWriter = new PrintWriter(stringWriter);\n throwable.printStackTrace(printWriter);\n printWriter.close();\n return stringWriter.toString();\n }"
1317
},
14-
"instructions": "Remove or conditionally disable debug print statements in production builds. Use a proper logging framework with appropriate log levels and ensure debug-level logging is disabled in production environments. Consider using build profiles or environment variables to control debug output."
18+
"instructions": "Possible active debug code detected. Deploying an application with debug code can create unintended entry points or expose sensitive information."
1519
},
1620
"locations": [
1721
{
18-
"file": ".mvn/wrapper/MavenWrapperDownloader.java",
19-
"line": 92,
20-
"snippet": " 89 | System.exit(0);\n 90 | } catch (Throwable e) {\n 91 | System.out.println(\"- Error downloading\");\n> 92 | e.printStackTrace();\n 93 | System.exit(1);\n 94 | }\n 95 | }",
21-
"category": "NEW"
22+
"file": "amazon-s3-quickstart/src/main/java/org/acme/s3/S3AsyncClientResource.java",
23+
"line": 56,
24+
"snippet": " 53 | })\n 54 | .onItem().ignore().andSwitchTo(Uni.createFrom().item(Response.created(null).build()))\n 55 | .onFailure().recoverWithItem(th -> {\n> 56 | th.printStackTrace();\n 57 | return Response.serverError().build();\n 58 | });\n 59 | }",
25+
"category": "EXISTING_REST"
2226
}
2327
],
2428
"metadata": {
2529
"total_occurrences": 1,
26-
"confidence": "low",
30+
"confidence": "medium",
2731
"safe_auto_apply": false,
2832
"estimated_time_seconds": 1
2933
}

packages/agents/tests/integration/test-outputs/attachments/group-java-spring-security-audit-spring-actuator-fully-enabled-spring-actuator-fully-enabled-high-semgrep-fix.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,30 @@
44
"rule": "java.spring.security.audit.spring-actuator-fully-enabled.spring-actuator-fully-enabled",
55
"tool": "semgrep",
66
"severity": "high",
7-
"description": "1. Disable unnecessary actuator endpoints using management.endpoints.web.exposure.exclude=env,logfile,heapdump\n2. Enable Spring Security with proper authentication for actuator endpoints\n3. Configure actuator security via spring.security.user.name and spring.security.user.password properties\n4. Restrict actuator access to specific IP ranges or internal networks only",
7+
"description": "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a significant security risk.",
88
"fix_pattern": {
99
"type": "template",
10+
"fixTier": 2,
11+
"fixerTool": "ai",
12+
"fixerCommand": "ai",
13+
"confidence": 85,
1014
"example": {
1115
"before": "",
12-
"after": "# Before (vulnerable)\n# spring.boot.admin.client.enabled=true\n\n# After (secure)\nmanagement.endpoints.web.exposure.exclude=env,logfile,heapdump\nmanagement.endpoints.web.exposure.include=health,info\nspring.security.user.name=admin\nspring.security.user.password=securePassword123"
16+
"after": "management.endpoints.web.exposure.include=health,info"
1317
},
14-
"instructions": "1. Disable unnecessary actuator endpoints using management.endpoints.web.exposure.exclude=env,logfile,heapdump\n2. Enable Spring Security with proper authentication for actuator endpoints\n3. Configure actuator security via spring.security.user.name and spring.security.user.password properties\n4. Restrict actuator access to specific IP ranges or internal networks only"
18+
"instructions": "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a significant security risk."
1519
},
1620
"locations": [
1721
{
1822
"file": "src/main/resources/application.properties",
19-
"line": 17,
20-
"snippet": " 14 | spring.messages.basename=messages/messages\n 15 | \n 16 | # Actuator\n> 17 | management.endpoints.web.exposure.include=*\n 18 | \n 19 | # Logging\n 20 | logging.level.org.springframework=INFO",
23+
"line": 18,
24+
"snippet": " 15 | spring.messages.basename=messages/messages\n 16 | \n 17 | # Actuator\n> 18 | management.endpoints.web.exposure.include=*\n 19 | \n 20 | # Logging\n 21 | logging.level.org.springframework=INFO",
2125
"category": "EXISTING_REST"
2226
}
2327
],
2428
"metadata": {
2529
"total_occurrences": 1,
26-
"confidence": "low",
30+
"confidence": "medium",
2731
"safe_auto_apply": false,
2832
"estimated_time_seconds": 1
2933
}

0 commit comments

Comments
 (0)