Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Fix source decompilation #409

Merged
merged 5 commits into from
Nov 9, 2023
Merged
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
19 changes: 17 additions & 2 deletions provider/internal/java/dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ func getMavenLocalRepoPath(mvnSettingsFile string) string {
func (p *javaServiceClient) GetDependenciesFallback(ctx context.Context, location string) (map[uri.URI][]*provider.Dep, error) {
deps := []*provider.Dep{}

m2Repo := getMavenLocalRepoPath(p.mvnSettingsFile)

path, err := filepath.Abs(p.findPom())
if err != nil {
return nil, err
Expand Down Expand Up @@ -145,6 +147,10 @@ func (p *javaServiceClient) GetDependenciesFallback(ctx context.Context, locatio
} else {
dep.Version = *d.Version
}
if m2Repo != "" && d.ArtifactID != nil && d.GroupID != nil {
dep.FileURIPrefix = filepath.Join(m2Repo,
strings.Replace(*d.GroupID, ".", "/", -1), *d.ArtifactID, dep.Version)
}
}
deps = append(deps, &dep)
}
Expand Down Expand Up @@ -247,7 +253,14 @@ func extractSubmoduleTrees(lines []string) [][]string {
continue
}

line = strings.TrimLeft(line, "[INFO] ")
line = strings.TrimPrefix(line, "[INFO] ")
line = strings.Trim(line, " ")

// output contains progress report lines that are not deps, skip those
if !(strings.HasPrefix(line, "+") || strings.HasPrefix(line, "|") || strings.HasPrefix(line, "\\")) {
continue
}

submoduleTrees[submod] = append(submoduleTrees[submod], line)
}
}
Expand Down Expand Up @@ -343,7 +356,9 @@ func (p *javaServiceClient) parseDepString(dep, localRepoPath string) (provider.
// Set some default or empty resolved identifier for the dependency.
d.ResolvedIdentifier = ""
} else {
d.ResolvedIdentifier = string(b)
// sometimes sha file contains name of the jar followed by the actual sha
sha, _, _ := strings.Cut(string(b), " ")
d.ResolvedIdentifier = sha
}

d.Labels = addDepLabels(p.depToLabels, d.Name)
Expand Down
92 changes: 62 additions & 30 deletions provider/internal/java/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ func resolveSourcesJars(ctx context.Context, log logr.Logger, location, mavenSet
}

args := []string{
"dependency:sources",
"-B",
"org.apache.maven.plugins:maven-dependency-plugin:3.6.2-SNAPSHOT:sources",
"-Djava.net.useSystemProxies=true",
}

Expand Down Expand Up @@ -416,61 +417,92 @@ func filterExistingSubmodules(artifacts []javaArtifact, pom *gopom.Project) []ja
return filtered
}

// parseUnresolvedSources takes the output from mvn dependency:sources and returns the artifacts whose sources
// could not be found.
func parseUnresolvedSources(output io.Reader) ([]javaArtifact, error) {
artifacts := []javaArtifact{}
unresolvedArtifacts := []javaArtifact{}
resolvedArtifacts := []javaArtifact{}
scanner := bufio.NewScanner(output)

sourcesPluginSeparatorSeen := false
unresolvedSeparatorSeen := false
sourcesPluginRegex := regexp.MustCompile(`maven-dependency-plugin:[\d\.]+:sources`)
resolvedSeparatorSeen, unresolvedSeparatorSeen := false, false
sourcesPluginRegex := regexp.MustCompile(`dependency:[\w.\-]+:sources`)
resolvedRegex := regexp.MustCompile(`The following files have been resolved`)
unresolvedRegex := regexp.MustCompile(`The following files have NOT been resolved`)
for scanner.Scan() {
line := scanner.Text()
line = strings.TrimLeft(line, "[INFO] ")
line = strings.TrimPrefix(line, "[INFO] ")
line = strings.Trim(line, " ")

if sourcesPluginRegex.Find([]byte(line)) != nil {
sourcesPluginSeparatorSeen = true
unresolvedSeparatorSeen = false
} else if unresolvedRegex.Find([]byte(line)) != nil {
unresolvedSeparatorSeen = true
} else if sourcesPluginSeparatorSeen && unresolvedSeparatorSeen {
line, _, _ = strings.Cut(line, "--") // ie: "org.apache.derby:derby:jar:10.14.2.0:test -- module derby (auto)"
resolvedSeparatorSeen = false
} else if resolvedRegex.Find([]byte(line)) != nil {
resolvedSeparatorSeen = true
unresolvedSeparatorSeen = false
} else if sourcesPluginSeparatorSeen && (unresolvedSeparatorSeen || resolvedSeparatorSeen) {
line, _, _ = strings.Cut(line, " --") // ie: "org.apache.derby:derby:jar:10.14.2.0:test -- module derby (auto)"

parts := strings.Split(line, ":")
if len(parts) != 6 && len(parts) != 5 {
// this is the last line which coincidently has 5 parts separated by :
if strings.Contains(line, "Finished") {
continue
}

// sometimes maven puts here artifacts that are not sources; don't count those as unresolved (ie: spring-petclinic project)
if len(parts) == 6 {
classifier := parts[3]
if classifier != "sources" {
continue
}
} else if len(parts) == 5 {
classifier := parts[2]
if classifier != "sources" {
continue
}
parts := strings.Split(line, ":")
if len(parts) != 5 {
continue
}

var version string
groupId := parts[0]
artifactId := parts[1]
if len(parts) == 6 {
if unresolvedSeparatorSeen {
version = parts[3]
} else {
version = parts[4]
}

artifact := javaArtifact{
packaging: JavaArchive,
ArtifactId: artifactId,
GroupId: groupId,
Version: version,
}

if unresolvedSeparatorSeen {
unresolvedArtifacts = append(unresolvedArtifacts, artifact)
} else {
version = parts[3]
resolvedArtifacts = append(resolvedArtifacts, artifact)
}
}
}

artifacts = append(artifacts,
javaArtifact{
packaging: JavaArchive,
ArtifactId: artifactId,
GroupId: groupId,
Version: version,
})
// Not resolved artifacts many times have actually been resolved, but for some reason
// they appear as not resolved, so the difference between the not resolved and the resolved
// is what we look for
result := []javaArtifact{}
for _, artifact := range unresolvedArtifacts {
if !contains(resolvedArtifacts, artifact) {
result = append(result, artifact)
}
}
return artifacts, scanner.Err()

return result, scanner.Err()
}

func contains(artifacts []javaArtifact, artifactToFind javaArtifact) bool {
if len(artifacts) == 0 {
return false
}

for _, artifact := range artifacts {
if artifact == artifactToFind {
return true
}
}

return false
}
20 changes: 8 additions & 12 deletions provider/internal/java/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ func Test_parseUnresolvedSources(t *testing.T) {
{
name: "valid sources output",
mvnOutput: `
[INFO] --- maven-dependency-plugin:3.5.0:sources (default-cli) @ spring-petclinic ---
[INFO] --- dependency:3.5.0:sources (default-cli) @ spring-petclinic ---
[INFO] The following files have been resolved:
[INFO] org.springframework.boot:spring-boot-starter-actuator:jar:sources:3.1.0 -- module spring.boot.starter.actuator [auto]
[INFO] org.springframework.boot:spring-boot-starter:jar:sources:3.1.0 -- module spring.boot.starter [auto]
[INFO] org.springframework.boot:spring-boot-starter-logging:jar:sources:3.1.0 -- module spring.boot.starter.logging [auto]
[INFO] org.apache.tomcat:tomcat-servlet-api:jar:sources:9.0.46 -- module tomcat.servlet.api (auto)
[INFO] com.fasterxml.jackson.core:jackson-core:jar:sources:2.12.3
[INFO] com.fasterxml.jackson.core:jackson-databind:jar:sources:2.12.3
[INFO] The following files have NOT been resolved:
[INFO] org.springframework.boot:spring-boot-starter-logging:jar:3.1.0:compile -- module spring.boot.starter.logging [auto]
[INFO] io.konveyor.demo:config-utils:jar:sources:1.0.0:compile
[INFO] org.apache.tomcat:tomcat-servlet-api:jar:9.0.46:provided -- module java.servlet
[INFO] com.fasterxml.jackson.core:jackson-core:jar:2.12.3:compile -- module com.fasterxml.jackson.core
[INFO] com.fasterxml.jackson.core:jackson-databind:jar:2.12.3:compile -- module com.fasterxml.jackson.databind
[INFO] io.konveyor.demo:config-utils:jar:1.0.0:compile -- module config.utils (auto)
[INFO] --- maven-dependency-plugin:3.5.0:sources (default-cli) @ spring-petclinic ---
[INFO] -----------------------------------------------------------------------------
[INFO] The following files have NOT been resolved:
Expand All @@ -37,12 +39,6 @@ func Test_parseUnresolvedSources(t *testing.T) {
ArtifactId: "config-utils",
Version: "1.0.0",
},
{
packaging: JavaArchive,
GroupId: "org.springframework.boot",
ArtifactId: "spring-boot-actuator",
Version: "3.1.0",
},
},
},
}
Expand Down