Java 프로젝트에서 사용하지 않거나 죽은 코드를 찾는 방법 [닫기]


306

대규모 Java 프로젝트에서 사용하지 않거나 죽은 코드를 찾기 위해 어떤 도구를 사용합니까? 우리 제품은 몇 년 동안 개발되어 왔으며 더 이상 사용하지 않는 코드를 수동으로 감지하기가 매우 어려워지고 있습니다. 그러나 사용하지 않는 코드는 가능한 많이 삭제하려고합니다.

일반적인 전략 / 기술에 대한 제안 (특정 도구 제외)도 높이 평가됩니다.

편집 : 우리는 이미 코드 범위 도구 (Clover, IntelliJ)를 사용하고 있지만 도움이 거의 없습니다. 데드 코드에는 여전히 단위 테스트가 있으며 적용되는 것으로 표시됩니다. 이상적인 도구는 다른 코드가 거의없는 코드 클러스터를 식별하여 문서 검사를 수동으로 수행 할 수 있다고 생각합니다.


16
단위 테스트는 별도의 소스 트리에 보관하고 (어쨌든해야 함) 라이브 트리에서만 적용 범위 도구를 실행하십시오.
agnul

5
IDEA의 "미사용 선언"검사로 시작 하고 테스트 소스 포함을 선택 취소 합니다 . IDEA의 "약간 도움이 없다"고 할 때의 의미를 명확하게 설명 할 수 있습니까?
David Moles

1
데드 코드를 찾는 방법 : 1) 외부에 링크되지 않았습니다. 2) 런타임에 링크되어 있어도 외부에서 사용되지 않았습니다. 3) 연결 및 호출되었지만 죽은 변수처럼 사용되지 않습니다. 4) 논리적으로 도달 할 수없는 상태. 따라서 링크, 시간이 지남에 따라 액세스, 논리 기반, 액세스 후 사용.
Muhammad Umer

IntelliJ Idea와 내 대답을 여기에서 사용하십시오 : stackoverflow.com/questions/22522013/… :)
BlondCode

David Mole의 답변에 추가 :이 답변 참조 stackoverflow.com/a/6587932/1579667
Benj

답변:


40

실행중인 시스템을 계측하여 코드 사용 로그를 유지 한 다음 몇 달 또는 몇 년 동안 사용되지 않은 코드 검사를 시작합니다.

예를 들어, 사용하지 않는 클래스에 관심이있는 경우 인스턴스가 작성 될 때 모든 클래스가 로깅되도록 인스트루먼트 될 수 있습니다. 그런 다음 작은 스크립트가이 로그를 전체 클래스 목록과 비교하여 사용하지 않는 클래스를 찾을 수 있습니다.

물론, 방법 수준에 들어가면 성능을 염두에 두어야합니다. 예를 들어, 메소드는 첫 번째 사용 만 기록 할 수 있습니다. 이것이 Java에서 어떻게 가장 잘 수행되는지 모르겠습니다. 우리는 이것을 동적 언어 인 스몰 토크 (Smalltalk)에서 수행했으며, 따라서 런타임에 코드를 수정할 수 있습니다. 우리는 로깅 호출로 모든 메소드를 계측하고 메소드가 처음으로 기록 된 후 로깅 코드를 제거하므로 일정 시간이 지나면 더 이상 성능 불이익이 발생하지 않습니다. 정적 부울 플래그를 사용하여 Java에서 비슷한 작업을 수행 할 수 있습니다 ...


5
나는이 답변을 좋아하지만 누구나 모든 클래스에 로깅을 명시 적으로 추가하지 않고 Java 로이 작업을 수행하는 방법을 알고 있습니까? 어쩌면 '프록시'마술일까요?
무법자 프로그래머

14
@ Outlaw AOP는 이에 대한 완벽한 사용 사례 인 것 같습니다.
파스칼 티 벤트

6
응용 프로그램의 클래스 로딩 구조를 이해하면 클래스 로더에서 AOP를 사용하여 클래스로드 이벤트를 추적 할 수 있습니다. 이것은 모든 생성자 이전의 조언보다 프로덕션 시스템에서 덜 침습적입니다.
ShabbyDoo

5
이 답변은 동적 언어에는 적합하지만 훨씬 더 나은 정적 언어에는 끔찍합니다. 정적으로 유형이 지정된 언어 (반사 제외)를 사용하면 어떤 방법이 사용되는지, 어떤 방법이 사용되지 않는지를 정확히 알 수 있습니다. 이것은 정적으로 유형이 지정된 언어의 가장 큰 장점 중 하나이므로 여기에 설명 된대로 오류가있는 방법이 아닌 언어를 사용해야합니다 .
Bill K

4
생각보다 @BillK 더 많은 반사가 발생합니다. 예를 들어 Spring은 반사를 포함하여 엄청나게 많은 마술을 수행합니다. 분석 도구가이를 모방해야합니다.
Thorbjørn Ravn Andersen

220

합리적으로 잘 작동하는 Eclipse 플러그인은 Unused Code Detector 입니다.

전체 프로젝트 또는 특정 파일을 처리하고 다양한 미사용 / 불량 코드 방법을 보여줄뿐만 아니라 가시성 변경을 제안합니다 (예 : 보호되거나 비공개 일 수있는 공용 방법).


멋져 보이지만 제대로 작동하지 못했습니다. "감지 ... 코드 감지"작업이 비활성화되어 있고이를 활성화 할 방법을 찾지 못했습니다.
Ondra Žižka

1
실제로 사용되지 않는 방법을 찾을 수 있습니다,하지만 난 비즈니스 위임 패턴 디자인을 사용하고 있기 때문에 (그들이있는 동안) 내 EJB를 사용하지 않는있는 것을 찾을 수 있습니까
Eildosa

그것은 여전히 ​​케플러에서 작동합니까? 출시는 이클립스 3.8에 대해 말 : ucdetector.org/releases.html
Mr_and_Mrs_D

케플러에서 완벽하게 작동하는 것 같습니다.
Erik Kaplun

4
마켓 플레이스 marketplace.eclipse.org/content/unnecessary-code-detector에 링크를 추가 하시겠습니까? 따라서 최신 버전의 Eclipse에서 지원되는지 여부를 쉽게 설치하고 질문에 답변 할 수 있습니다.
토마스 웰러

64

CodePro 는 최근 Eclipse 프로젝트와 함께 Google에서 출시했습니다. 무료이며 매우 효과적입니다. 플러그인에는 하나 / 많은 진입 점이 있는 ' Dead Code 찾기 '기능이 있습니다. 꽤 잘 작동합니다.


1
일식 케플러에서는 더 이상 작동하지 않습니다. 업데이트 사이트를 통해 성공적으로 설치하면 매번 일식 충돌이 발생합니다.
txulu

불행히도이 도구는 Spring의 존재를 인식하지 못하는 것 같습니다. 따라서 모든 @Components를 사용하지 않는 것으로 잘못 표시합니다.
Clint Eastwood

아주 나이가되다 더 이상 Last updated this plugin March 27, 2012 개발자를
만나지

2
모든 링크가 오래되었습니다.
zygimantus

3
불행히도 Google은 Eclipse 프로젝트에서 코드를 덤프하여 모든 것을 잊어 버린 것으로 보입니다.
Thorbjørn Ravn Andersen

30

나는 ProGuard 가 여기에 언급되지 않았다는 것에 놀랐 습니다. 가장 성숙한 제품 중 하나입니다.

ProGuard 는 무료 Java 클래스 파일 축소 기, 최적화 프로그램, 난독 화기 및 사전 검증기입니다. 사용하지 않는 클래스, 필드, 메소드 및 속성을 감지하고 제거합니다. 바이트 코드를 최적화하고 사용하지 않는 명령어를 제거합니다. 의미없는 짧은 이름을 사용하여 나머지 클래스, 필드 및 메서드의 이름을 바꿉니다. 마지막으로 Java 6 또는 Java Micro Edition의 처리 된 코드를 사전 검증합니다.

ProGuard의 일부 용도는 다음과 같습니다.

  • 더 작은 코드 아카이브, 더 빠른 네트워크 전송, 더 빠른 로딩 및 더 작은 메모리 풋 프린트를위한 더 콤팩트 한 코드 작성.
  • 프로그램과 라이브러리를 리버스 엔지니어링하기 어렵게 만듭니다.
  • 죽은 코드를 나열하여 소스 코드에서 제거 할 수 있습니다.
  • 빠른 클래스 로딩을 최대한 활용하기 위해 Java 6 이상의 기존 클래스 파일을 대상으로 지정하고 사전 검증합니다.

데드 코드 목록의 예는 다음과 같습니다. https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode


8
샘플 사용법을 제공하면 더 나은 답변을 얻을 수 있습니다.
rds

1
설명서를 읽고, 나는 그것을 사용하지 않는 코드를 축소 것을 볼 수 있지만, 그것은 어디 어디에서도 찾을 수없는 나열 이 - 예를 합의, 또는 문서의 관련 섹션에 링크가 매우 도움이 될 것입니다!
orbfish

26

Eclipse에서 단일 클래스의 것으로 알려진 한 가지 방법은 모든 메소드를 개인용으로 변경 한 다음 어떤 불만이 있는지 확인하는 것입니다. 사용되는 메서드의 경우 오류가 발생하고 가능한 가장 낮은 액세스 수준으로 되돌립니다. 사용하지 않는 메소드의 경우, 사용되지 않은 메소드에 대한 경고가 발생하여 삭제 될 수 있습니다. 그리고 보너스로 종종 비공개로 만들 수있는 공개 방법을 찾을 수 있습니다.

그러나 그것은 매우 수동적입니다.


4
아마도 이상적인 대답은 아니지만 정말 영리합니다.
Erik Reppen 2013

8
이것은 다른 클래스의 사용되지 않은 코드에서 호출 할 때까지 영리합니다.
Danosaure

이 방법을 반복하면 사용 된 방법 중 하나가 제거되면 다른 방법이 생성되므로 엄청난 양의 코드가 제거 될 수 있습니다.
4myle

15

테스트 적용 범위 도구를 사용하여 코드베이스를 계측 한 다음 테스트가 아닌 응용 프로그램 자체를 실행하십시오.

EmmaEclemma 는 특정 코드 실행에 대해 어떤 클래스가 실행되는지에 대한 훌륭한 보고서를 제공합니다.


1
+1은 좋은 시작점이기는하지만 사용되지 않은 (아직 선언 된) 변수도 녹색으로 나타납니다.
DerMike

13

코드베이스의 풍부한 리팩토링 환경에서 펑크를 식별하기 위해 버그 찾기 를 사용하기 시작했습니다 . 또한 코드 101 의 아키텍처에서 너무 복잡한 스팟을 식별하기 위해 Structure 101 을 고려 하여 실제 늪이 어디에 있는지 알 수 있습니다.


4
FindBugs는 죽은 코드와 사용하지 않은 코드를 감지 할 수없고 사용되지 않은 필드 만 감지합니다. 이 답변을 참조하십시오 .
Stefan Mücke

12

이론적으로는 사용하지 않는 코드를 결정적으로 찾을 수 없습니다. 이것에 대한 수학적 증거가 있습니다 (이것은 더 일반적인 정리의 특별한 경우입니다). 궁금한 점이 있으면 Halting Problem을 찾으십시오.

이것은 여러 가지 방법으로 Java 코드로 나타날 수 있습니다.

  • 사용자 입력, 구성 파일, 데이터베이스 항목 등을 기반으로 클래스로드
  • 외부 코드 로딩;
  • 객체 트리를 타사 라이브러리로 전달
  • 기타

즉, IDEA IntelliJ를 선택한 IDE로 사용하며 모듈, 사용하지 않는 메소드, 사용하지 않는 멤버, 사용하지 않는 클래스 등 간의 findign 종속성에 대한 광범위한 분석 도구를 가지고 있습니다. 태그는 사용되지 않지만 공개 방법은보다 광범위한 분석이 필요합니다.


1
입력 해 주셔서 감사합니다. 우리는 IntelliJ를 사용하고 있으며 거기에서 도움을 받고 있습니다. 중단 문제와 결정 불가능성에 대해서는 이론에 익숙하지만 결정적인 해결책이 필요하지 않습니다.
knatten

12
첫 문장이 너무 강하다. Halting Problem (종종 잘못 인용 / 거부 된)과 마찬가지로 완전한 일반적인 해결책은 없지만 탐지 할 수있는 특별한 경우가 많이 있습니다.
joel.neely

9
평가 및 / 또는 리플렉션을 사용하는 언어에 대한 일반적인 솔루션은 없지만 코드에 도달 할 수없는 경우가 많습니다.
pjc50

1
리플렉션이없고 전체 소스 코드를 사용하면 정적으로 유형이 지정된 언어를 사용하면 사용하지 않는 모든 코드를 결정하기가 매우 쉽습니다.
Bill K

리플렉션이나 외부 발신자에 의해 도달 할 수없는 것을 찾을 수는 없지만 주어진 진입 점 또는 진입 점 세트에서 정적으로 도달 할 수없는 코드를 찾을 수 있습니다.
nafg

8

Eclipse에서 Windows> 환경 설정> Java> 컴파일러> 오류 / 경고로 이동
하여 모두 오류로 변경하십시오. 모든 오류를 수정하십시오. 이것이 가장 간단한 방법입니다. 아름다움은 이렇게하면 코드를 작성할 때 정리할 수 있다는 것입니다.

스크린 샷 Eclipse Code :

여기에 이미지 설명을 입력하십시오


5

IntelliJ에는 사용되지 않는 코드를 감지하는 코드 분석 도구가 있습니다. 공개되지 않은 필드 / 메소드 / 클래스를 최대한 많이 작성해야하며 더 많은 미사용 메소드 / 필드 / 클래스가 표시됩니다.

또한 코드 볼륨을 줄이는 방법으로 중복 코드를 찾으려고 노력합니다.

마지막 제안은 오픈 소스 코드를 찾으려면 사용하면 코드가 더 간단 해집니다.


이러한 도구가 무엇인지에 대한 예가 있습니까?
orbfish

@orbfish 당신은 실행할 수 있습니다 Analyse=> Run inspection by name=>unused
Peter Lawrey


3

DCD는 일부 IDE의 플러그인은 아니지만 개미 또는 독립형에서 실행할 수 있습니다. 정적 도구처럼 보이며 PMD와 FindBugs가 할 수없는 일을 할 수 있습니다 . 나는 그것을 시도 할 것이다.

추신 아래 코멘트에서 언급했듯이 프로젝트는 현재 GitHub있습니다 .


이 코멘트하지 응답으로 내려 가야한다
카운트

DCD가 "지금 죽었다"는 진술을 제거하려면 답변을 업데이트하십시오. 버전 2.1은 12 일 전에 릴리스되었습니다 . 또한 답변의 링크가 작동하지 않습니다.
skomisa

2

코드를 프로파일 링하고 코드 범위 데이터를 제공하는 도구가 있습니다. 이를 통해 (코드가 실행될 때) 얼마나 호출되는지 확인할 수 있습니다. 이 도구 중 하나를 사용하면 얼마나 많은 고아 코드가 있는지 확인할 수 있습니다.


2
  • FindBugs는 이런 종류의 일에 탁월합니다.
  • PMD (Project Mess Detector)는 사용할 수있는 또 다른 도구입니다.

그러나 작업 공간에서 사용되지 않는 공용 정적 메소드 는 찾을 수 없습니다 . 누구든지 그러한 도구를 알고 있다면 알려주십시오.


1

EMMA와 같은 사용자 범위 도구 그러나 정적 도구는 아닙니다 (즉, 실제로 회귀 테스트 및 가능한 모든 오류 사례를 통해 응용 프로그램을 실행해야합니다.)

여전히 EMMA는 매우 유용합니다.


1

Emma, ​​Cobertura 및 Clover와 같은 코드 적용 툴은 코드를 계측하고 일련의 테스트를 실행하여 호출되는 코드 부분을 기록합니다. 이것은 매우 유용하며 개발 프로세스에서 없어서는 안될 부분입니다. 테스트 스위트가 코드를 얼마나 잘 다루는 지 식별하는 데 도움이됩니다.

그러나 이것은 실제 데드 코드를 식별하는 것과 다릅니다. 테스트에서 다루거나 다루지 않는 코드 만 식별합니다. 이렇게하면 오 탐지 (테스트가 모든 시나리오를 다루지 않는 경우)와 오 탐지 (실제 시나리오에서 실제로 사용되지 않은 코드에 액세스하는 경우)를 얻을 수 있습니다.

죽은 코드를 실제로 식별하는 가장 좋은 방법은 실제 실행 환경에서 적용 범위 도구를 사용하여 코드를 계측하고 장기간에 걸쳐 코드 적용 범위를 분석하는 것입니다.

로드 밸런싱 된 중복 환경에서 실행중인 경우 (그렇지 않은 경우, 그렇지 않은 이유는 무엇입니까?) 애플리케이션의 한 인스턴스 만 계측하고로드 밸런서를 임의의 작은 크기로 구성하는 것이 합리적이라고 가정합니다. 사용자는 인스트루먼트 된 인스턴스에서 실행됩니다. 장기간에 걸쳐이 작업을 수행하는 경우 (계절 변화와 같은 실제 사용 시나리오를 모두 포함했는지 확인하기 위해) 실제 사용에서 액세스하는 코드 영역과 해당 파트를 정확하게 확인할 수 있어야합니다. 실제로 액세스하지 않으므로 코드가 죽은 것입니다.

나는 이것을 개인적으로 본 적이 없으며 앞서 언급 한 도구를 사용하여 테스트 스위트를 통해 호출되지 않는 코드를 계측하고 분석하는 방법을 모릅니다.


1

Java 프로젝트 인 Dead Code Detector (DCD)가 있습니다. 소스 코드의 경우 잘 작동하지 않지만 .jar 파일의 경우 정말 좋습니다. 또한 클래스 및 방법별로 필터링 할 수 있습니다.



0

Eclipse는 도달 할 수없는 코드를 표시 / 강조 표시 할 수 있습니다. JUnit은 코드 커버리지를 보여줄 수 있지만 테스트가 필요하며 관련 테스트가 누락되었거나 코드가 실제로 사용되지 않는지 결정해야합니다.


3
Eclipse는 메소드의 범위가 로컬 (즉, 개인)인지 만 알려줍니다. 그럼에도 불구하고 당신은 100 % 확신 할 수 없습니다 ... 반사 전용 메소드는 외부에서 호출 될 수 있습니다.
p3t0r

0

코드를 계측하고 사용되고 사용되지 않은 코드를 강조 표시하는 Clover 범위 도구를 찾았습니다. Google CodePro Analytics와 달리 WebApplications에서도 작동합니다 (내 경험에 따라 Google CodePro에 대해 틀릴 수 있습니다).

내가 주목 한 유일한 단점은 Java 인터페이스를 고려하지 않는다는 것입니다.


Affict, 그것은 무료 서버 측 CI 도구입니다.
Erik Kaplun

0

나는 Doxygen을 사용하여 결코 호출되지 않은 메소드를 찾기 위해 메소드 호출 맵을 개발합니다. 그래프에는 호출자가없는 메소드 군집이 있습니다. 항상 일부 주요 진입 점에서 시작해야하므로 라이브러리에서는 작동하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.