Bagaimana menemukan kode yang tidak digunakan / mati dalam proyek java [ditutup]

306

Alat apa yang Anda gunakan untuk menemukan kode yang tidak digunakan / mati dalam proyek-proyek java besar? Produk kami telah dikembangkan selama beberapa tahun, dan semakin sulit untuk secara manual mendeteksi kode yang tidak lagi digunakan. Namun kami mencoba untuk menghapus kode yang tidak terpakai sebanyak mungkin.

Saran untuk strategi / teknik umum (selain alat khusus) juga dihargai.

Sunting: Perhatikan bahwa kami sudah menggunakan alat cakupan kode (Clover, IntelliJ), tetapi ini sedikit membantu. Kode mati masih memiliki unit test, dan muncul sebagai tertutup. Saya kira alat yang ideal akan mengidentifikasi kelompok kode yang memiliki sangat sedikit kode lain tergantung padanya, memungkinkan untuk melakukan pemeriksaan manual.

Knatten
sumber
16
Simpan tes unit di pohon sumber terpisah (Anda harus tetap) dan jalankan alat cakupan hanya pada pohon hidup.
agnul
5
Saya akan mulai dengan inspeksi "Deklarasi Tidak Terpakai" IDEA dan hapus centang Sertakan sumber pengujian . Bisakah Anda mengklarifikasi apa yang Anda maksud ketika Anda mengatakan "sedikit bantuan" IDEA?
David Moles
1
Cara menemukan kode mati: 1) tidak ditautkan oleh apa pun di luar. 2) belum digunakan dari luar meskipun tertaut dalam runtime. 3) Tertaut & Dipanggil tetapi tidak pernah digunakan seperti variabel mati. 4) keadaan tidak terjangkau secara logis. Jadi menghubungkan, mengakses dari waktu ke waktu, berdasarkan logika, gunakan setelah mengakses.
Muhammad Umer
Gunakan Ide IntelliJ dan jawaban saya dari sini: stackoverflow.com/questions/22522013/… :)
BlondCode
Tambahan untuk jawaban David Mole: lihat jawaban ini stackoverflow.com/a/6587932/1579667
Benj

Jawaban:

40

Saya akan instrumen sistem yang berjalan untuk menyimpan log penggunaan kode, dan kemudian mulai memeriksa kode yang tidak digunakan selama berbulan-bulan atau bertahun-tahun.

Misalnya jika Anda tertarik pada kelas yang tidak digunakan, semua kelas bisa diinstrumentasi untuk mencatat ketika instance dibuat. Dan kemudian skrip kecil dapat membandingkan log ini dengan daftar kelas lengkap untuk menemukan kelas yang tidak digunakan.

Tentu saja, jika Anda mengikuti level metode, Anda harus selalu mengingat kinerja. Misalnya, metode hanya bisa mencatat penggunaan pertama mereka. Saya tidak tahu bagaimana ini paling baik dilakukan di Jawa. Kami telah melakukan ini di Smalltalk, yang merupakan bahasa yang dinamis dan karenanya memungkinkan untuk modifikasi kode saat runtime. Kami instrumen semua metode dengan panggilan logging dan menghapus kode logging setelah metode telah login untuk pertama kalinya, sehingga setelah beberapa waktu tidak ada lagi hukuman kinerja terjadi. Mungkin hal serupa dapat dilakukan di Jawa dengan bendera boolean statis ...

akuhn
sumber
5
Saya suka jawaban ini tetapi apakah ada yang punya ide bagaimana melakukan ini di Jawa tanpa secara eksplisit menambahkan logging di setiap kelas? Mungkin sihir 'Proksi'?
Penjahat Programmer
14
@Outlaw AOP tampaknya kasus penggunaan yang sempurna untuk ini.
Pascal Thivent
6
Jika Anda memahami struktur classloading aplikasi, Anda bisa menggunakan AOP pada classloader untuk melacak peristiwa classload. Ini akan kurang invasif pada sistem produksi daripada saran sebelum semua konstruktor.
ShabbyDoo
5
Jawaban ini cukup bagus untuk bahasa yang dinamis tetapi mengerikan untuk bahasa statis yang bisa melakukan JAUH lebih baik. Dengan bahasa yang diketik secara statis (selain dari refleksi) Anda dapat mengetahui dengan pasti metode mana yang digunakan dan mana yang tidak, ini adalah salah satu keuntungan terbesar dari bahasa yang diketik secara statis dan Anda harus menggunakannya daripada metode yang bisa salah seperti dijelaskan di sini .
Bill K
4
@BillK refleksi lebih banyak terjadi daripada yang Anda pikirkan. Misalnya Spring melakukan sedikit sihir di bawah selimut, termasuk refleksi. Alat analisis Anda harus meniru itu.
Thorbjørn Ravn Andersen
220

Plugin Eclipse yang berfungsi dengan baik adalah Detektor Kode yang Tidak Digunakan .

Ini memproses seluruh proyek, atau file tertentu dan menunjukkan berbagai metode kode yang tidak digunakan / mati, serta menyarankan perubahan visibilitas (yaitu metode publik yang dapat dilindungi atau pribadi).

Mikezx6r
sumber
Terlihat bagus tapi saya tidak bisa membuatnya berfungsi - tindakan "Deteksi kode ..." dinonaktifkan dan saya tidak menemukan cara untuk mengaktifkannya.
Ondra Žižka
1
Memang menemukan metode yang tidak digunakan, TETAPI juga menemukan bahwa EJB saya sedang tidak digunakan (sementara mereka) karena saya menggunakan desain pola delegasi bisnis
Eildosa
Apakah masih bekerja pada kepler? rilis mengatakan tentang eclipse 3.8: ucdetector.org/releases.html
Mr_and_Mrs_D
Tampaknya dalam kondisi kerja yang sempurna di Kepler.
Erik Kaplun
4
Apakah Anda ingin menambahkan tautan ke marketplace marketplace.eclipse.org/content/unn Diperlukan-code- detector ? Ini membuatnya lebih mudah untuk menginstal dan menjawab pertanyaan apakah itu didukung pada versi Eclipse yang lebih baru.
Thomas Weller
64

CodePro baru-baru ini dirilis oleh Google dengan proyek Eclipse. Ini gratis dan sangat efektif. Plugin ini memiliki fitur ' Cari Kode Mati ' dengan satu / banyak titik masuk. Bekerja dengan cukup baik.

Berlin Brown
sumber
1
Tidak akan bekerja lagi dengan gerhana Kepler. Setelah berhasil menginstalnya melalui situs pembaruan, itu membuat gerhana setiap kali.
txulu
Sayangnya, sepertinya alat ini tidak menyadari keberadaan Spring, oleh karena itu, ini akan menandai semua @Components saya sebagai tidak terpakai, salah
Clint Eastwood
Menjadi sangat tua Tidak berfungsi lagi Last updated this plugin March 27, 2012 developer.google.com/java-dev-tools/download-codepro
mumair
2
Semua tautan sudah usang.
zygimantus
3
Sayangnya tampaknya Google membuang kode pada proyek Eclipse dan melupakan semuanya.
Thorbjørn Ravn Andersen
30

Saya terkejut ProGuard belum disebutkan di sini. Ini adalah salah satu produk paling matang di sekitar.

ProGuard adalah shrinker, optimizer, obfuscator, dan preverifier file kelas Java gratis. Ini mendeteksi dan menghapus kelas, bidang, metode, dan atribut yang tidak digunakan. Ini mengoptimalkan bytecode dan menghapus instruksi yang tidak digunakan. Itu mengubah nama kelas yang tersisa, bidang, dan metode menggunakan nama pendek yang tidak berarti. Akhirnya, ini memverifikasi kode yang diproses untuk Java 6 atau untuk Java Micro Edition.

Beberapa penggunaan ProGuard adalah:

  • Membuat kode yang lebih ringkas, untuk arsip kode yang lebih kecil, transfer yang lebih cepat di seluruh jaringan, pemuatan yang lebih cepat, dan jejak kaki memori yang lebih kecil.
  • Membuat program dan perpustakaan lebih sulit untuk direkayasa ulang.
  • Daftar kode mati, sehingga dapat dihapus dari kode sumber.
  • Penargetan ulang dan preverifikasi file kelas yang ada untuk Java 6 atau lebih tinggi, untuk mengambil keuntungan penuh dari pemuatan kelas yang lebih cepat.

Berikut contoh kode mati daftar: https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode

David d C e Freitas
sumber
8
Memberikan contoh penggunaan akan membuat jawaban yang lebih baik.
rds
1
Membaca dokumentasi, saya melihat bahwa itu menyusut kode yang tidak digunakan, tetapi saya tidak dapat menemukan di mana saja daftar itu - setuju, contoh, atau tautan ke bagian yang relevan dari dokumentasi, akan sangat membantu!
orbfish
26

Satu hal yang saya ketahui dilakukan di Eclipse, pada satu kelas, adalah mengubah semua metodenya menjadi pribadi dan kemudian melihat keluhan apa yang saya dapatkan. Untuk metode yang digunakan, ini akan memancing kesalahan, dan saya mengembalikannya ke tingkat akses terendah yang saya bisa. Untuk metode yang tidak digunakan, ini akan memancing peringatan tentang metode yang tidak digunakan, dan itu bisa dihapus. Dan sebagai bonus, Anda sering menemukan beberapa metode publik yang dapat dan harus dibuat pribadi.

Tapi ini sangat manual.

skiphoppy
sumber
4
Mungkin bukan jawaban yang ideal tetapi itu benar-benar pintar.
Erik Reppen
8
Ini pintar ... sampai Anda mendapat panggilan dari kode yang tidak digunakan dari kelas lain.
Danosaure
Iterasi atas metode ini dapat menghapus petak kode yang sangat besar karena salah satu metode yang digunakan membuat yang lain setelah dihapus.
4myle
15

Gunakan alat cakupan tes untuk instrumen basis kode Anda, kemudian jalankan aplikasi itu sendiri, bukan tes.

Emma dan Eclemma akan memberi Anda laporan bagus tentang berapa persen dari kelas apa yang dijalankan untuk setiap menjalankan kode.

jamesh
sumber
1
Memberi +1 untuk itu adalah titik awal yang baik tetapi perlu diingat bahwa mis. Variabel yang belum digunakan (belum dinyatakan) akan muncul hijau juga.
DerMike
13

Kami sudah mulai menggunakan Find Bugs untuk membantu mengidentifikasi beberapa funk di lingkungan basis kode kami yang kaya untuk refactor. Saya juga akan mempertimbangkan Structure 101 untuk mengidentifikasi bintik-bintik dalam arsitektur basis kode Anda yang terlalu rumit, sehingga Anda tahu di mana rawa-rawa yang sebenarnya.

Alan
sumber
4
FindBugs tidak dapat mendeteksi kode mati dan tidak terpakai, hanya bidang yang tidak terpakai. Lihat jawaban ini .
Stefan Mücke
12

Secara teori, Anda tidak dapat secara pasti menemukan kode yang tidak digunakan. Ada bukti matematis dari ini (well, ini adalah kasus khusus dari teorema yang lebih umum). Jika Anda penasaran, cari Masalah Pemutusan.

Ini dapat memanifestasikan dirinya dalam kode Java dalam banyak cara:

  • Memuat kelas berdasarkan input pengguna, file konfigurasi, entri basis data, dll;
  • Memuat kode eksternal;
  • Melewati pohon objek ke perpustakaan pihak ketiga;
  • dll.

Yang sedang berkata, saya menggunakan IDEA IntelliJ sebagai IDE pilihan saya dan memiliki alat analisis yang luas untuk dependensi antara modul, metode yang tidak digunakan, anggota yang tidak digunakan, kelas yang tidak digunakan, dll. Cukup cerdas juga seperti metode pribadi yang tidak dipanggil adalah ditandai tidak terpakai tetapi metode publik membutuhkan analisis yang lebih luas.

cletus
sumber
1
Terima kasih atas masukannya. Kami menggunakan IntelliJ, dan mendapatkan bantuan di sana. Mengenai Masalah Pemutusan dan ketidakpastian, saya akrab dengan teori ini, tetapi kita tidak perlu membutuhkan solusi deterministik.
Knatten
12
Kalimat pembuka terlalu kuat. Seperti Masalah Pemutusan (juga sering salah kutip / dilecehkan), tidak ada solusi umum yang lengkap, tetapi ada banyak kasus khusus yang layak dideteksi.
joel.neely
9
Meskipun tidak ada solusi umum untuk bahasa dengan eval dan / atau refleksi, ada banyak kasus di mana kode terbukti tidak terjangkau.
pjc50
1
Tanpa refleksi dan dengan kode sumber lengkap, bahasa yang diketik secara statis akan membuatnya cukup mudah untuk secara deterministik menemukan semua kode yang tidak digunakan.
Bill K
Anda tidak dapat menemukan bahwa itu dapat dibuktikan tidak dapat dijangkau oleh refleksi atau oleh penelepon eksternal, tetapi Anda dapat menemukan kode yang dapat dibuktikan tidak dapat dijangkau secara statis dari titik masuk yang diberikan atau set titik masuk
nafg
8

Di Eclipse Goto Windows> Preferensi> Java> Compiler> Kesalahan / Peringatan
dan ubah semuanya menjadi kesalahan. Perbaiki semua kesalahan. Ini adalah cara paling sederhana. Keindahannya adalah ini akan memungkinkan Anda untuk membersihkan kode saat Anda menulis.

Kode Cuplikan Layar:

masukkan deskripsi gambar di sini

smileprem
sumber
5

IntelliJ memiliki alat analisis kode untuk mendeteksi kode yang tidak digunakan. Anda harus mencoba membuat sebanyak mungkin bidang / metode / kelas sebagai non-publik dan itu akan menunjukkan lebih banyak metode / bidang / kelas yang tidak digunakan

Saya juga akan mencoba mencari kode duplikat sebagai cara mengurangi volume kode.

Saran terakhir saya adalah mencoba mencari kode sumber terbuka yang jika digunakan akan membuat kode Anda lebih sederhana.

Peter Lawrey
sumber
Adakah contoh alat ini?
orbfish
@orbfish Anda dapat menjalankan Analyse=> Run inspection by name=>unused
Peter Lawrey
5

Perspektif slice Structure101 akan memberikan daftar (dan grafik dependensi) dari setiap "yatim" atau " kelompok yatim " kelas atau paket yang tidak memiliki dependensi ke atau dari "utama" cluster.

Chris Chedgey - Structure101
sumber
Apakah ini berfungsi misalnya variabel / metode dalam kelas?
Joeblackdev
Bagaimana saya tahu kalau ini seharusnya bekerja dengan misalnya Eclipse 4.3?
Erik Kaplun
3

DCD bukanlah plugin untuk beberapa IDE tetapi dapat dijalankan dari semut atau mandiri. Sepertinya alat statis dan dapat melakukan apa yang PMD dan FindBugs tidak bisa . Saya akan mencobanya.

PS Seperti yang disebutkan dalam komentar di bawah, Proyek tinggal sekarang di GitHub .

Heiner
sumber
Ini harus turun sebagai komentar bukan jawaban
Hitung
Harap perbarui jawaban Anda untuk menghapus pernyataan Anda bahwa DCD "tampak mati sekarang". Versi 2.1 dirilis 12 hari yang lalu . Juga, tautan dalam jawaban Anda tidak berfungsi.
skomisa
2

Ada alat yang kode profil dan menyediakan data kode cakupan. Ini memungkinkan Anda melihat (saat kode dijalankan) berapa banyak yang dipanggil. Anda dapat memperoleh alat-alat ini untuk mencari tahu berapa banyak kode yatim yang Anda miliki.

Vaibhav
sumber
2
  • FindBugs sangat baik untuk hal semacam ini.
  • PMD (Project Mess Detector) adalah alat lain yang dapat digunakan.

Namun, tidak ada yang dapat menemukan metode statis publik yang tidak digunakan di ruang kerja. Jika ada yang tahu alat seperti itu maka tolong beri tahu saya.

graveca
sumber
1

Alat jangkauan pengguna, seperti EMMA. Tapi itu bukan alat statis (yaitu itu benar-benar harus menjalankan aplikasi melalui pengujian regresi, dan melalui semua kasus kesalahan yang mungkin, yang, yah, tidak mungkin :))

Meski begitu, EMMA sangat bermanfaat.

Vladimir Dyuzhev
sumber
1

Alat cakupan kode, seperti Emma, ​​Cobertura, dan Clover, akan menginstrumentasi kode Anda dan mencatat bagian mana yang dipanggil dengan menjalankan serangkaian tes. Ini sangat berguna, dan harus menjadi bagian integral dari proses pengembangan Anda. Ini akan membantu Anda mengidentifikasi seberapa baik test suite Anda mencakup kode Anda.

Namun, ini tidak sama dengan mengidentifikasi kode mati nyata. Ini hanya mengidentifikasi kode yang dicakup (atau tidak dicakup) oleh tes. Ini dapat memberi Anda positif palsu (jika tes Anda tidak mencakup semua skenario) serta negatif palsu (jika tes Anda mengakses kode yang sebenarnya tidak pernah digunakan dalam skenario dunia nyata).

Saya membayangkan cara terbaik untuk benar-benar mengidentifikasi kode mati adalah dengan instrumen kode Anda dengan alat cakupan di lingkungan live running dan untuk menganalisis cakupan kode selama periode waktu yang panjang.

Jika Anda menjalankan dalam lingkungan redundan seimbang beban (dan jika tidak, mengapa tidak?) Maka saya kira masuk akal untuk hanya instrumen satu contoh aplikasi Anda dan untuk mengkonfigurasi penyeimbang beban Anda sedemikian rupa sehingga secara acak, tetapi kecil, bagian dari pengguna Anda berjalan pada instance yang diinstrumentasi. Jika Anda melakukan ini selama periode waktu yang lama (untuk memastikan bahwa Anda telah membahas semua skenario penggunaan dunia nyata - variasi musiman seperti itu), Anda harus dapat melihat dengan tepat area kode mana yang diakses di bawah penggunaan dunia nyata dan bagian mana benar-benar tidak pernah diakses dan karenanya kode mati.

Saya belum pernah melihat ini dilakukan secara pribadi, dan tidak tahu bagaimana alat-alat tersebut dapat digunakan untuk instrumen dan menganalisis kode yang tidak dipanggil melalui test suite - tetapi saya yakin mereka bisa melakukannya.

Vihung
sumber
1

Ada proyek Java - Dead Code Detector (DCD). Untuk kode sumber sepertinya tidak berfungsi dengan baik, tetapi untuk file .jar - ini sangat bagus. Plus, Anda dapat memfilter menurut kelas dan metode.

Lukasz Czerwinski
sumber
0

Eclipse dapat menampilkan / menyorot kode yang tidak dapat dijangkau. JUnit dapat menunjukkan cakupan kode kepada Anda, tetapi Anda akan memerlukan beberapa tes dan harus memutuskan apakah tes yang relevan hilang atau kode tersebut benar-benar tidak digunakan.

Matthias Winkelmann
sumber
3
Eclipse hanya akan memberi tahu Anda jika ruang lingkup metode ini lokal (mis. Pribadi); dan bahkan kemudian Anda tidak dapat 100% yakin ... dengan metode pribadi refleksi dapat dipanggil dari luar.
p3t0r
0

Saya menemukan alat cakupan Clover yang instrumen kode dan menyoroti kode yang digunakan dan yang tidak digunakan. Tidak seperti Google CodePro Analytics, itu juga berfungsi untuk Aplikasi Web (sesuai pengalaman saya dan saya mungkin salah tentang Google CodePro).

Satu-satunya kelemahan yang saya perhatikan adalah tidak membutuhkan antarmuka Java.

Kashif Nazar
sumber
Afaict, ini adalah alat CI sisi server yang tidak bebas.
Erik Kaplun
0

Saya menggunakan Doxygen untuk mengembangkan metode panggilan peta untuk menemukan metode yang tidak pernah dipanggil. Pada grafik Anda akan menemukan pulau-pulau cluster metode tanpa penelepon. Ini tidak berfungsi untuk perpustakaan karena Anda harus selalu mulai dari beberapa titik masuk utama.

jbruni
sumber