我在 IntelijIdea 中运行一个项目没有任何问题。当我尝试从这样的命令运行时:
GITHUB_TOKEN
的环境变量。mvn clean install
构建应用程序。github-analyzer.jar
目录下生成target
文件。target
导航到 cd target
目录。java -jar github-analyzer-1.0-SNAPSHOT.jar
运行应用程序。`maven 运行,但在最后一个命令中我收到此错误:
错误:无法初始化主类GitHubAnalyzer
引起原因:java.lang.NoClassDefFoundError:
org/kohsuke/github/GHFileNotFoundException
这是我的代码,我做错了什么吗?
import org.kohsuke.github.*;
import io.github.cdimascio.dotenv.Dotenv;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class GitHubAnalyzer {
public static String GITHUB_TOKEN;
static {
Dotenv dotenv = Dotenv.load();
GITHUB_TOKEN = dotenv.get("GITHUB_TOKEN");
}
public static final long WEEK_IN_MILLIS = 7L * 24 * 3600 * 1000;
public static void main(String[] args) throws IOException {
if(GITHUB_TOKEN.isEmpty()) {
System.err.println("Please set the GITHUB_TOKEN environment variable");
return;
}
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("GitHub Analyzer");
System.out.println("Insert owner:");
String owner = scanner.next();
System.out.println("Insert repository:");
String repository = scanner.next();
System.out.println("What do you want to analyze?");
System.out.println("1. Pair of contributors that worked on the same file");
System.out.println("2. Contributions of contributors in the last week");
int choice = scanner.nextInt();
GitHub github;
try {
github = new GitHubBuilder().withOAuthToken(GITHUB_TOKEN).build();
}catch (IOException e){
System.err.println("An error occurred while accessing GitHub: " + e.getMessage());
return;
}
analyzeRepository(github, owner, repository, choice);
} catch (IOException e) {
System.err.println("An error occurred while analyzing the repository: " + e.getMessage());
}
}
private static void analyzeRepository(GitHub github, String owner, String repository, int choice) throws IOException {
GHRepository repo;
try {
repo = github.getRepository(owner + "/" + repository);
} catch (GHFileNotFoundException e) {
System.out.println("Repository not found");
return;
}catch (IOException e){
System.out.println("An error occurred while accessing the repository: " + e.getMessage());
return;
}
List<GHCommit> commits = new ArrayList<>();
try {
commits = repo.listCommits().withPageSize(100).toList();
}catch (IOException e){
System.out.println("An error occurred while accessing the repository: " + e.getMessage());
return;
}
int numOfCommits = commits.size();
Map<String,List<GHCommit>> commitsByAuthor = commits.stream()
.filter(commit -> {
try {
return commit.getAuthor() != null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.groupingBy(commit -> {
try {
return commit.getAuthor().getLogin();
} catch (IOException e) {
throw new RuntimeException(e);
}
}));
List<GHRepository.Contributor> contributors = repo.listContributors().toList();
Date weekAgo = new Date(System.currentTimeMillis() - WEEK_IN_MILLIS);
AtomicInteger counter = new AtomicInteger(0);
Map<String,Set<String>> contributorsFileMap = new ConcurrentHashMap<>();
if (choice == 1) {
analyzeContributorsPairs(repo, commits, numOfCommits, counter, contributorsFileMap, contributors);
} else if(choice == 2){
analyzeContributorsContributions(repo, commitsByAuthor, weekAgo, counter, contributors);
}
}
private static void analyzeContributorsContributions(GHRepository repo, Map<String, List<GHCommit>> commitsByAuthor, Date weekAgo, AtomicInteger counter, List<GHRepository.Contributor> contributors) throws IOException {
System.out.println("Analyzing contributors contributions");
for(GHRepository.Contributor contributor:contributors){
List<GHCommit> commitsByThisAuthor = commitsByAuthor.getOrDefault(contributor.getLogin(),Collections.emptyList());
analyzeContributor(repo, contributor, weekAgo,commitsByThisAuthor);
}
}
private static void analyzeContributorsPairs(GHRepository repo, List<GHCommit> commits, int numOfCommits, AtomicInteger counter, Map<String, Set<String>> contributorsFileMap, List<GHRepository.Contributor> contributors) {
System.out.println("Analyzing contributors pairs");
commits.forEach((commit)-> parseCommit(commit, counter, numOfCommits, contributorsFileMap));
displayResult(getTopPairs(contributorsFileMap));
}
private static void analyzeContributor(GHRepository repo, GHRepository.Contributor contributor, Date weekAgo, List<GHCommit> commitsByThisAuthor) throws IOException {
System.out.println("Analyzing contributor: " + contributor.getLogin());
int linesOfCode = 0;
int commitsNo;
int mergeRequests;
int maxCharsInComment = 0;
List<GHCommit> commits = commitsByThisAuthor.stream()
.filter(commit -> {
try {
return commit.getCommitDate().after(weekAgo);
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
commitsNo = commits.size();
for(GHCommit commit : commits) {
for(GHCommit.File file : commit.getFiles()) {
linesOfCode += file.getLinesAdded();
}
}
List<GHPullRequest> pullRequests = repo.getPullRequests(GHIssueState.ALL)
.stream().filter(ghPullRequest -> {
try {
return (ghPullRequest.getUser().getLogin().equals(contributor.getLogin()) && ghPullRequest.getCreatedAt().after(weekAgo));
} catch (IOException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
mergeRequests = pullRequests.size();
List<GHPullRequestReviewComment> comments = new ArrayList<>();
pullRequests.stream().map(ghPullRequest -> {
try {
return ghPullRequest.listReviewComments();
} catch (IOException e) {
throw new RuntimeException(e);
}
}).forEach(ghPullRequestReviewComments -> {
try {
comments.addAll(ghPullRequestReviewComments.toList());
} catch (IOException e) {
throw new RuntimeException(e);
}
});
maxCharsInComment = comments.stream().
map(GHPullRequestReviewComment::getBody).
map(String::length).max(Integer::compareTo).orElse(0);
System.out.println("Contributor: " + contributor.getLogin());
System.out.println("Lines of code: " + linesOfCode);
System.out.println("Commits: " + commitsNo);
System.out.println("Merge requests: " + mergeRequests);
System.out.println("Max chars in comment: " + maxCharsInComment);
System.out.println("\n\n");
}
private static List<Map.Entry<String,Integer>> getTopPairs(Map<String, Set<String>> contributorsFileMap) {
Map<String, Integer> pairFrequency = new HashMap<>();
for(Set<String> contributors : contributorsFileMap.values()) {
List<String> contributorList = new ArrayList<>(contributors);
for(int i = 0; i < contributorList.size(); i++) {
for(int j = i + 1; j < contributorList.size(); j++) {
String pair = contributorList.get(i) + " - " + contributorList.get(j);
pairFrequency.put(pair, pairFrequency.getOrDefault(pair, 0) + 1);
}
}
}
return pairFrequency.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toList());
}
private static void displayResult(List<Map.Entry<String, Integer>> sortedPairs) {
if(sortedPairs.isEmpty()) {
System.out.println("\n\nNo contributors pairs found");
return;
}
System.out.println("\n\nTop contributors pairs:");
sortedPairs.stream().limit(10).forEach(pair -> {
System.out.println(pair.getKey() + " : " + pair.getValue());
});
}
private static void parseCommit(GHCommit commit, AtomicInteger counter, int numOfCommits, Map<String, Set<String>> contributorsFileMap) {
int count = counter.incrementAndGet();
int percentage = (int) (((double) count / numOfCommits) * 100);
getProgressBar(percentage);
try {
Optional.ofNullable(commit.getAuthor())
.map(GHPerson::getLogin)
.ifPresent(author->{
try {
commit.getFiles().stream().map(GHCommit.File::getFileName).forEach(filename -> {
contributorsFileMap.computeIfAbsent(filename, k -> new HashSet<>()).add(author);
});
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void getProgressBar(int percentage) {
StringBuilder progressBar = new StringBuilder("[");
for(int i = 0; i < 50; i++) {
if(i < percentage / 2) {
progressBar.append("=");
} else {
progressBar.append(" ");
}
}
progressBar.append("] " + percentage + "%");
System.out.print("\r" + progressBar.toString());
}
}
您的项目的 pom.xml 是什么样的?它是否有 org.kohsuke.github 作为依赖项?鉴于没有类定义的错误,这将是我首先要查找的地方。