Last active
July 1, 2024 08:18
-
-
Save thomasdarimont/f387a8352ad76cb00223476b0c74a03b to your computer and use it in GitHub Desktop.
PoC for fetching the Java source code of an artifact from a maven repository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package demo; | |
import com.github.javaparser.JavaParser; | |
import com.github.javaparser.ast.CompilationUnit; | |
import com.github.javaparser.ast.body.MethodDeclaration; | |
import org.eclipse.aether.DefaultRepositorySystemSession; | |
import org.eclipse.aether.RepositorySystem; | |
import org.eclipse.aether.RepositorySystemSession; | |
import org.eclipse.aether.artifact.Artifact; | |
import org.eclipse.aether.artifact.DefaultArtifact; | |
import org.eclipse.aether.repository.LocalRepository; | |
import org.eclipse.aether.repository.RemoteRepository; | |
import org.eclipse.aether.resolution.ArtifactRequest; | |
import org.eclipse.aether.resolution.ArtifactResolutionException; | |
import org.eclipse.aether.resolution.ArtifactResult; | |
import org.eclipse.aether.supplier.RepositorySystemSupplier; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.nio.charset.StandardCharsets; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.StandardCopyOption; | |
import java.util.Collections; | |
import java.util.Optional; | |
import java.util.jar.JarEntry; | |
import java.util.jar.JarFile; | |
public class GetMethodSourceDemo { | |
static class MavenResolver { | |
private static RepositorySystem newRepositorySystem() { | |
return new RepositorySystemSupplier().get(); | |
} | |
public static RepositorySystemSession newRepositorySystemSession(RepositorySystem system) { | |
DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); | |
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, new LocalRepository("target/local-repo"))); | |
return session; | |
} | |
public static File resolveArtifact(String groupId, String artifactId, String version) throws ArtifactResolutionException { | |
RepositorySystem system = newRepositorySystem(); | |
RepositorySystemSession session = newRepositorySystemSession(system); | |
Artifact artifact = new DefaultArtifact(groupId, artifactId, "sources", "jar", version); | |
ArtifactRequest request = new ArtifactRequest(); | |
request.setArtifact(artifact); | |
request.setRepositories(Collections.singletonList(new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build())); | |
ArtifactResult result = system.resolveArtifact(session, request); | |
return result.getArtifact().getFile(); | |
} | |
} | |
static class SourceExtractor { | |
public static String readSourceFile(File jarFile, String className) throws IOException { | |
try (JarFile jar = new JarFile(jarFile)) { | |
String entryName = className.replace('.', '/') + ".java"; | |
JarEntry entry = jar.getJarEntry(entryName); | |
if (entry != null) { | |
try (InputStream input = jar.getInputStream(entry)) { | |
Path tempFile = Files.createTempFile("source-", ".java"); | |
Files.copy(input, tempFile, StandardCopyOption.REPLACE_EXISTING); | |
return new String(Files.readAllBytes(tempFile), StandardCharsets.UTF_8); | |
} | |
} else { | |
throw new IOException("Source file for class " + className + " not found in JAR"); | |
} | |
} | |
} | |
} | |
static class MethodExtractor { | |
public static String getMethodSource(String sourceCode, String methodName) { | |
CompilationUnit cu = new JavaParser().parse(sourceCode).getResult().orElseThrow(); | |
Optional<MethodDeclaration> method = cu.findAll(MethodDeclaration.class).stream().filter(m -> m.getNameAsString().equals(methodName)).findFirst(); | |
return method.map(MethodDeclaration::toString).orElse(null); | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
File sourceFile = MavenResolver.resolveArtifact("org.springframework", "spring-core", "6.1.10"); | |
String sourceCode = SourceExtractor.readSourceFile(sourceFile, "org.springframework.util.Assert"); | |
String methodSource = MethodExtractor.getMethodSource(sourceCode, "assignableCheckFailed"); | |
System.out.println("Method source: \n" + methodSource); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>com.github.thomasdarimont.training</groupId> | |
<artifactId>java-workbench</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
</parent> | |
<groupId>org.example</groupId> | |
<artifactId>lib-maven-aether</artifactId> | |
<properties> | |
<java.version>22</java.version> | |
<java.release>22</java.release> | |
<maven-aether.version>1.1.0</maven-aether.version> | |
<javaparser.version>3.26.0</javaparser.version> | |
<maven-resolver.version>1.9.20</maven-resolver.version> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-api</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-spi</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-supplier</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-util</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-impl</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-connector-basic</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-transport-http</artifactId> | |
<version>${maven-resolver.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.maven.resolver</groupId> | |
<artifactId>maven-resolver-transport-file</artifactId> | |
<version>1.9.13</version> | |
</dependency> | |
<dependency> | |
<groupId>com.github.javaparser</groupId> | |
<artifactId>javaparser-core</artifactId> | |
<version>${javaparser.version}</version> | |
</dependency> | |
</dependencies> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment