JavaRush /Java blogi /Random-UZ /IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtiri...
Viacheslav
Daraja

IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak)

Guruhda nashr etilgan
"G'ildirakni qayta ixtiro qilmang" - bu muvaffaqiyatli va samarali ishning asosiy qoidalaridan biri. Lekin o'z g'ildiragini qayta ixtiro qilishni istamasangiz, nima qilish kerak, lekin boshqa birovning rul g'ildiragi egri bo'lib chiqadi va g'ildiraklar kvadrat bo'ladi? Ushbu sharh boshqa odamlarning kutubxonalarini "oxirgi chora sifatida" tuzatish texnikasi va buni kompyuteringizga qanday kengaytirish haqida iloji boricha qisqacha ma'lumot berish uchun mo'ljallangan.
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish) - 1

Kirish

Biz hammamiz u yoki bu vositadan foydalanamiz. Ammo ba'zida asboblar to'liq mos kelmaydi yoki xatolar mavjud. Java tilining xususiyatlari tufayli biz kerakli joylarda asboblarning harakatini to'g'rilashimiz mumkin. Biz loyihalarga hissa qo'shsak va jalb qilish so'rovlarini yuborsak yaxshi (bu erda ko'proq o'qishingiz mumkin: “ GitHub - Loyihalarga hissa qo'shish ”). Ammo ular darhol qabul qilinmasligi yoki hatto qabul qilinmasligi mumkin. Lekin loyiha ehtiyojlari uchun hozir kerak. Va bu erda, umid qilamanki, ushbu maqola biz ishlab chiquvchilar sifatida mavjud bo'lgan vositalarni ko'rsatadi. Biz gaplashadigan quyidagi amallarni bajarishimiz kerak:
  • Masalan, sinov dasturini tayyorlang (Hibernate loyihasi misolidan foydalanib)
  • O'zgaruvchan joyni topish
  • O'zgartirish kiritish
  • Repozitariyni joylashtirish
Quyidagi barcha qadamlar Windows OS uchun berilgan, ammo nix tizimlari uchun analoglari mavjud. Shunday qilib, agar kerak bo'lsa, ularni takrorlashingiz mumkin.

Mavzuga tayyorgarlik

Shunday qilib, bizga sinov loyihasi kerak. Kutish biz uchun ideal, chunki... bu "zamonaviy, moda, zamonaviy". Men juda ko'p tafsilotga kirmayman, chunki ... Maqola Hibernate haqida emas. Biz hamma narsani tez va aniq bajaramiz. Va biz, to'g'ri ishlab chiquvchilar kabi, qurish tizimidan foydalanamiz. Misol uchun, Gradle biz uchun ham mos keladi, bu maqola uchun o'rnatilishi kerak ( https://gradle.org/install/ ). Birinchidan, biz loyiha yaratishimiz kerak. Mavenning buning uchun arxetiplari bor va Gradleda buning uchun maxsus plagin mavjud: Gradle Init . Shunday qilib, buyruq qatorini sizga ma'lum bo'lgan har qanday usulda oching. Loyiha uchun katalog yarating, unga o'ting va buyruqni bajaring:

mkdir javarush 
cd javarush 
gradle init --type java-application
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish) - 2
Loyihani import qilishdan oldin, qanday qilib qurishni tasvirlaydigan faylga ba'zi o'zgarishlar kiritaylik. Bu fayl qurish skripti deb ataladi va build.gradle deb nomlanadi. U biz gradle init-ni bajargan katalogda joylashgan. Shuning uchun biz uni shunchaki ochamiz (masalan, Windowsda start build.gradle buyrug'i bilan). Biz u erda " bog'liqlar " blokini topamiz, ya'ni. bog'liqliklar. Biz foydalanadigan barcha uchinchi tomon bankalari bu erda tasvirlangan. Endi biz bu erda nimani tasvirlashni tushunishimiz kerak. Keling, Hibernate veb-saytiga o'tamiz ( http://hibernate.org/ ). Biz Hibernate ORM bilan qiziqamiz . Bizga oxirgi versiya kerak. Chapdagi menyuda "Relizlar" kichik bo'limi mavjud. "Oxirgi barqaror" ni tanlang. Pastga aylantiring va "Asosiy dastur (JPA o'z ichiga oladi)" ni toping. Ilgari JPA qo'llab-quvvatlashini alohida ulash kerak edi, ammo endi hamma narsa soddalashdi va faqat bitta qaramlik etarli. Shuningdek, biz Hibernate yordamida ma'lumotlar bazasi bilan ishlashimiz kerak bo'ladi. Buning uchun eng oddiy variantni olaylik - H2 ma'lumotlar bazasi . Tanlov amalga oshirildi, bu erda bizning bog'liqliklarimiz:

dependencies {
    // Базовая зависимость для Hibernate (новые версии включают и JPA)
    compile 'org.hibernate:hibernate-core:5.2.17.Final'
    // База данных, к которой мы будем подключаться
    compile 'com.h2database:h2:1.4.197'
    // Use JUnit test framework
    testCompile 'junit:junit:4.12'
}
Ajoyib, keyin nima bo'ladi? Hibernate rejimini sozlashimiz kerak. Hibernate rejimida " Ishga kirishish bo'yicha qo'llanma " mavjud, ammo bu ahmoqona va yordamdan ko'ra ko'proq to'siqdir. Shuning uchun, keling, to'g'ri odamlar kabi to'g'ridan-to'g'ri " Foydalanuvchi qo'llanmasi " ga boraylik. Mundarijada biz " Bootstrap " bo'limini ko'ramiz, bu "Bootstrapping" deb tarjima qilinadi. Sizga kerak bo'lgan narsa. U erda juda ko'p aqlli so'zlar yozilgan, ammo gap shundaki, sinf yo'lida META-INF katalogi va persistence.xml fayli bo'lishi kerak. Standartga ko'ra, sinf yo'li "resurslar" katalogini o'z ichiga oladi. Shuning uchun biz belgilangan katalogni yaratamiz: mkdir src\main\resources\META-INF u erda persistence.xml faylini yarating va uni oching. Hujjatlarda "268-misol. META-INF/persistence.xml konfiguratsiya fayli" misoli mavjud bo'lib, undan tarkibni olib, uni persistence.xml fayliga joylashtiramiz. Keyin IDE-ni ishga tushiring va unga yaratilgan loyihamizni import qiling. Endi biz ma'lumotlar bazasiga biror narsani saqlashimiz kerak. Bu mavjudlik deb ataladigan narsa. Ob'ektlar domen modeli deb ataladigan narsani ifodalaydi. Va tarkibda, mana, biz " 2. Domen modeli " ni ko'ramiz. Biz matnni pastga tushamiz va "2.1. Xaritalash turlari" bobida ob'ektning oddiy misolini ko'ramiz. Keling, uni biroz qisqartirib, o'zimizga olaylik:
package entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity(name = "Contact")
public class Contact {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    public Contact(String name) {
        this.name = name;
    }
}
Endi bizda ob'ektni ifodalovchi sinf mavjud. Keling, persistence.xml ga qaytaylik va u erda bitta joyni to'g'rilaymiz: Ko'rsatilgan joyda classbiz sinfimizni ko'rsatamiz entity.Contact. Ajoyib, qolgani ishga tushirish. Keling, Bootstrap bo'limiga qaytaylik . Bizni maxsus EE muhiti (ya'ni, biz uchun muayyan tizim xatti-harakatlarini amalga oshiradigan muhit) bilan ta'minlaydigan dastur serverimiz yo'qligi sababli biz SE muhitida ishlaymiz. Buning uchun biz uchun faqat "Misol 269. Ilova bootstrapped EntityManagerFactory" misoli mos keladi. Masalan, buni qilaylik:
public class App {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CRM");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        Contact contact = new Contact("Vasya");
        em.persist(contact);
        em.getTransaction().commit();
        Query sqlQuery = em.createNativeQuery("select count(*) from contact");
        BigInteger count = (BigInteger) sqlQuery.getSingleResult();
        emf.close();
        System.out.println("Entiries count: " + count);
    }
}
Huray, mavzuimiz tayyor. Men bu qismni o'tkazib yuborishni xohlamadim , chunki ... Keyingi boblar uchun mavzuimiz qanday paydo bo'lganini tushunish tavsiya etiladi.

O'zgartirilishi mumkin bo'lgan xatti-harakatni topish

Keling, BigInteger tipidagi hisoblash maydonini ishga tushirish joyini olamiz va u erda to'xtash nuqtalarini o'rnatamiz ( BreakPoint ). Kerakli qatorga kiritgandan so'ng, buni Ctrl+F8 tugmalari yordamida yoki Run -> Toggle Line Breakpoint menyusi orqali amalga oshirish mumkin. Keyin biz disk raskadrovkada asosiy usulimizni ishga tushiramiz (Run -> Debug):
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 3
Biroz noqulay misol, lekin deylik, ishga tushirishda so'rovlar bo'shliqlari sonini o'zgartirmoqchimiz. Ko'rib turganimizdek, bizning sqlQuery NativeQueryImpl. ni bosing Ctrl+N, sinf nomini yozing va unga o'ting. Shunday qilib, biz sinfga borganimizda, biz ushbu sinf joylashgan joyga o'tamiz va avtoulovni yoqamiz:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 4
Darhol ta'kidlaymizki, Idea hozirda dasturning manba kodini (manba kodi, ya'ni) qaerdan topishni bilmaydi. Shuning uchun u biz uchun sinf faylidan tarkibni muloyimlik bilan dekompilyatsiya qildi:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 5
Shuni ham yodda tutingki, IntelliJ Idea oynasining sarlavhasida Gradle biz uchun artefaktni qaerda saqlashi yozilgan. Keling, artefaktimiz joylashgan yo'l haqida fikr yuritamiz:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 6
Buyruq yordamida buyruq satrida ushbu katalogga o'tamiz cd way to каталогу. Men darhol eslatma qilaman: agar loyihani manbadan qurish mumkin bo'lsa, manbadan qurish yaxshidir. Masalan, Hibernate manba kodi rasmiy veb-saytda mavjud. Uni kerakli versiya uchun tanlash va u erda barcha o'zgarishlarni amalga oshirish va loyihada ko'rsatilgan qurilish skriptlari yordamida yig'ish yaxshiroqdir. Men maqolada eng dahshatli variantni taqdim etaman - kavanoz bor, lekin manba kodi yo'q. Va eslatma raqami 2: Gradle plaginlar yordamida manba kodini olishi mumkin. Tafsilotlar uchun Gradle yordamida jar uchun javadocs va manbalarni qanday yuklab olishni ko'ring .

O'zgartirish kiritish

Biz o'zgartirayotgan sinf qaysi paketga mos ravishda katalog strukturasini qayta yaratishimiz kerak. Bunday holda: mkdir org\hibernate\query\internal, shundan so'ng biz ushbu katalogda fayl yaratamiz NativeQueryImpl.java. Endi biz ushbu faylni ochamiz va sinfning barcha mazmunini u erda IDE dan nusxalaymiz (Idea biz uchun dekompilyatsiya qilgan bir xil). Kerakli qatorlarni o'zgartiring. Masalan:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 7
Endi faylni kompilyatsiya qilaylik. Biz bajaramiz: javac org\hibernate\query\internal\NativeQueryImpl.java. Voy, siz uni olib, xatosiz kompilyatsiya qila olmaysiz. Biz bir qator belgilarni topib bo'lmaydigan xatolarni oldik, chunki... o'zgaruvchan sinf boshqa sinflar bilan bog'langan bo'lib, IntelliJ Idea odatda biz uchun sinf yo'liga qo'shadi. Bizning IDE-larning barcha foydaliligini his qilyapsizmi? =) Xo'sh, o'zimiz qo'shamiz, biz ham qila olamiz. Keling, quyidagi yo'llarni ko'rsatamiz:
  • [1] - hibernate-yadro-5.2.17.Final.jar
  • [2] - hibernate-jpa-2.1-api-1.0.0.Final.jar
Xuddi biz qilganimizdek: "Tashqi kutubxonalar" da "Loyiha" ko'rinishida biz kerakli kavanozni topamiz va ni bosing Ctrl+Shift+C. Endi quyidagi buyruqni yaratamiz va bajaramiz: javac -cp [1];[2] org\hibernate\query\internal\NativeQueryImpl.java Natijada java fayli yonida yangi sinf fayllari paydo bo'ladi, ular jar faylida yangilanishi kerak:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 8
Huray, endi siz jar yangilanishini amalga oshirishingiz mumkin. Rasmiy materiallarga amal qilishimiz mumkin : jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class Open IntelliJ Idea sizga fayllarni o'zgartirishga ruxsat bermaydi. Shuning uchun, kavanozni yangilashni amalga oshirishdan oldin, ehtimol siz Idea-ni yopishingiz kerak bo'ladi va yangilangandan keyin uni oching. Shundan so'ng siz IDE-ni qayta ochib, dubugni qayta ishga tushirishingiz mumkin. IDE qayta ishga tushirilishi o'rtasida tanaffus nuqtalari tiklanmaydi. Shunday qilib, dasturning bajarilishi avvalgi joyda to'xtaydi. Voila, biz o'zgarishlarimiz qanday ishlashini ko'ramiz:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish kerak) - 9
Ajoyib. Ammo bu erda savol tug'iladi - nima tufayli? Shunchaki, gradle loyihani qurishda bog'liqliklar va omborlar bloklarini tahlil qiladi. Gradle-da ma'lum bir o'rnatish keshi bor, u ma'lum bir joyda joylashgan (" Gradle kesh joylashuvini qanday o'rnatish kerak? " ga qarang. Agar keshda bog'liqlik bo'lmasa, Gradle uni ombordan yuklab oladi. Biz jarni o'zgartirganimiz uchun Keshning o‘zi, keyin Gradl kutubxona keshda va hech narsani chiqarib tashlamaydi, deb o‘ylaydi.Lekin keshni har qanday tozalash bizning o‘zgarishlarimiz yo‘qolishiga olib keladi.Bundan tashqari, bizdan boshqa hech kim borib ularni olishi mumkin emas.Qanchalik noqulaylik. , shunday emasmi? Nima qilish kerak. Hmm, ombordan yuklab olishlar? Demak, bizga imtiyozlar va shoirlar bilan bizning omborimiz kerak. Bu keyingi qadam.

Repozitariyni joylashtirish

Sizning omboringizni joylashtirish uchun turli xil bepul echimlar mavjud: ulardan biri Artifactory , ikkinchisi esa Apache Archive . Artifactory moda, zamonaviy, zamonaviy ko'rinadi, lekin men u bilan qiyinchiliklarga duch keldim, artefaktlarni to'g'ri joylashtirishni xohlamadim va noto'g'ri maven metama'lumotlarini yaratdim. Shuning uchun, kutilmaganda o'zim uchun Apache versiyasi men uchun ishladi. Bu unchalik chiroyli emasligi ma'lum bo'ldi, lekin u ishonchli ishlaydi. Yuklab olish sahifasida mustaqil versiyani qidiring va uni oching. Ularning o'zlarining " Tez boshlash " lari bor. Ishga tushgandan so'ng, manzilni kutishingiz kerak http://127.0.0.1:8080/#repositorylist. Shundan so'ng, "Artifaktni yuklash" ni tanlang:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish) - 10
"Yuklashni boshlash" tugmasini bosing va keyin "Fayllarni saqlash" tugmasini bosing. Shundan so'ng, yashil muvaffaqiyat xabari paydo bo'ladi va artefakt "Browse" bo'limida mavjud bo'ladi. Buni jar va pom fayllari uchun qilish kerak:
IntelliJ Idea: dekompilyatsiya, kompilyatsiya, almashtirish (yoki boshqa odamlarning xatolarini qanday tuzatish) - 11
Buning sababi, pom faylida qo'shimcha kutish rejimiga bog'liqliklar ko'rsatilgan. Va bizda faqat 1 qadam qoldi - bizning qurish skriptimizda omborni belgilang:

repositories {
    jcenter()
    maven {
        url "http://127.0.0.1:8080/repository/internal/"
    }
}
Va shunga ko'ra, bizning hibernatsiya versiyasi quyidagicha bo'ladi: compile 'org.hibernate:hibernate-core:5.2.17.Final-JAVARUSH'. Hammasi shu, endi bizning loyihamiz asl nusxadan emas, balki biz tuzatgan versiyadan foydalanadi.

Xulosa

Biz tanishganga o'xshaymiz. Umid qilamanki, qiziqarli bo'ldi. Bunday "hiylalar" kamdan-kam hollarda amalga oshiriladi, lekin agar to'satdan sizning biznes talablaringiz siz foydalanadigan kutubxonalar qondira olmaydigan shartlarni o'rnatsa, nima qilish kerakligini bilasiz. Ha, bu yo'l bilan tuzatish mumkin bo'lgan bir nechta misollar:
  • Undertow deb nomlangan veb-server mavjud. Bir muncha vaqtgacha proksi-serverdan foydalanganda oxirgi foydalanuvchining IP-manzilini aniqlashga imkon bermagan xatolik mavjud edi.
  • Hozircha WildFly JPA spetsifikatsiya tomonidan hisobga olinmagan bir lahzani ma'lum bir tarzda ko'rib chiqdi, chunki bu Istisnolar tashlandi. Va uni sozlash mumkin emas edi.
#Viacheslav
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION