JavaRush /Java Blogu /Random-AZ /IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və...
Viacheslav
Səviyyə

IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar)

Qrupda dərc edilmişdir
“Çəkəri yenidən kəşf etməyin” uğurlu və səmərəli iş üçün əsas qaydalardan biridir. Bəs öz təkərinizi yenidən ixtira etmək istəmədiyiniz halda, başqasının sükanı əyri və təkərlər kvadrat formada olduqda nə etməli? Bu icmalın məqsədi digər insanların kitabxanalarını “son çarə kimi” düzəltmək və bunu kompüterinizə necə genişləndirmək barədə mümkün qədər qısa məlumat verməkdir.
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 1

Giriş

Hamımız bu və ya digər vasitələrdən istifadə edirik. Ancaq bəzən alətlər tamamilə uyğun deyil və ya səhvlər var. Java dilinin xüsusiyyətləri sayəsində biz lazım olan yerlərdə alətlərin davranışını düzəldə bilirik. Layihələrə töhfə vermək və cəlbedici sorğular göndərmək yaxşıdır (daha ətraflı burada oxuya bilərsiniz: “ GitHub - Layihələrə töhfə vermək ”). Amma onlar dərhal qəbul olunmaya bilər, hətta qəbul olunmaya da bilər. Amma layihənin ehtiyacları üçün indi lazımdır. Və burada, ümid edirəm ki, bu məqalə tərtibatçılar olaraq bizim üçün mövcud olan vasitələri göstərəcəkdir. Haqqında danışacağımız aşağıdakı addımları yerinə yetirməli olacağıq:
  • Məsələn, sınaq proqramı hazırlayın (Hibernate layihəsinin nümunəsindən istifadə etməklə)
  • Dəyişən bir yer tapmaq
  • Dəyişiklik etmək
  • Anbarın yerləşdirilməsi
Aşağıdakı bütün addımlar Windows OS üçün verilmişdir, lakin nix sistemləri üçün analoqları var. Beləliklə, lazım olduqda onları təkrarlaya bilərsiniz.

Mövzu Hazırlığı

Beləliklə, bir sınaq layihəsinə ehtiyacımız var. Qış rejimi bizim üçün idealdır, çünki... bu "şık, dəbli, müasir". Çox təfərrüata varmayacağam, çünki... Məqalə Hibernate haqqında deyil. Biz hər şeyi tez və nöqtəyə çatdıracağıq. Biz, düzgün tərtibatçılar kimi, tikinti sistemindən istifadə edəcəyik. Məsələn, Gradle bizim üçün də uyğundur, bu məqalə üçün quraşdırılmalıdır ( https://gradle.org/install/ ). Əvvəlcə bir layihə yaratmalıyıq. Maven-in bunun üçün arxetipləri var və Gradle-də bunun üçün xüsusi plagin var: Gradle Init . Beləliklə, əmr satırını sizə məlum olan hər hansı bir şəkildə açın. Layihə üçün bir kataloq yaradın, ona gedin və əmri yerinə yetirin:

mkdir javarush 
cd javarush 
gradle init --type java-application
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya başqalarının səhvlərini necə düzəltmək olar) - 2
Layihəni idxal etməzdən əvvəl, necə qurulacağını təsvir edən faylda bəzi dəyişikliklər edək. Bu fayl build skripti adlanır və build.gradle adlanır. O, gradle init-i icra etdiyimiz kataloqda yerləşir. Buna görə də biz onu sadəcə açırıq (məsələn, Windows-da start build.gradle əmri ilə). Biz orada “ asılılıqlar ” blokunu tapırıq, yəni. asılılıqlar. İstifadə edəcəyimiz bütün üçüncü tərəf bankaları burada təsvir edilmişdir. İndi burada nəyi təsvir edəcəyimizi başa düşməliyik. Gəlin Hibernate veb saytına gedək ( http://hibernate.org/ ). Biz Hibernate ORM ilə maraqlanırıq . Ən son buraxılışa ehtiyacımız var. Soldakı menyuda "Buraxılışlar" alt bölməsi var. "Son stabil" seçin. Aşağı diyirləyin və "Əsas tətbiqetmə (JPA daxildir)" tapın. Əvvəllər JPA dəstəyini ayrıca birləşdirmək lazım idi, lakin indi hər şey sadələşdi və yalnız bir asılılıq kifayətdir. Biz həmçinin Hibernate istifadə edərək verilənlər bazası ilə işləməliyik. Bunu etmək üçün ən sadə variantı götürək - H2 verilənlər bazası . Seçim edilir, burada asılılıqlarımız var:

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'
}
Əla, sonra nə olacaq? Hibernate'i konfiqurasiya etməliyik. Hibernate-in " Başlanğıc Bələdçisi " var, lakin o, axmaqdır və köməkdən daha çox maneədir. Buna görə də gəlin düzgün insanlar kimi birbaşa “ İstifadəçi təlimatına ” keçək. Mündəricatda biz bölməni görürük “ Bootstrap ”, “Bootstrap” kimi tərcümə olunur. Sadəcə sizə lazım olan. Orada çoxlu ağıllı sözlər yazılıb, amma məsələ ondadır ki, sinif yolunda META-INF kataloqu və persistence.xml faylı olmalıdır. Standarta görə, sinif yolu "resurslar" kataloqunu ehtiva edir. Buna görə də, göstərilən kataloqu yaradırıq: mkdir src\main\resources\META-INF Orada persistence.xml faylını yaradın və açın. Orada sənədlərdə məzmunu götürüb persistence.xml faylına daxil edəcəyimiz “Nümunə 268. META-INF/persistence.xml konfiqurasiya faylı” nümunəsi var. Sonra, IDE-ni işə salın və yaradılmış layihəmizi ona idxal edin. İndi verilənlər bazasında bir şey saxlamalıyıq. Bu varlıq deyilən bir şeydir. Müəssisələr sözdə domen modelindən bir şeyi təmsil edir. Və məzmun cədvəlində, bax, biz “ 2. Domain Modeli ” görürük. Biz mətni aşağı endirərək “2.1. Xəritəçəkmə növləri” fəslində obyektin sadə nümunəsinə baxırıq. Bir az qısaldaraq özümüzə götürək:
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;
    }
}
İndi bir varlığı təmsil edən bir sinifimiz var. Gəlin persistence.xml-ə qayıdıb orada bir yeri düzəldək: Göstərilən yerdə classbiz öz sinfimizi göstərəcəyik entity.Contact. Əla, qalan yalnız işə salmaqdır. Gəlin Bootstrap fəslinə qayıdaq . Bizi xüsusi EE mühiti ilə təmin edəcək proqram serverimiz olmadığından (yəni bizim üçün müəyyən sistem davranışını həyata keçirən mühit), biz SE mühitində işləyirik. Bunun üçün bizə yalnız “Nümunə 269. Proqram yüklənmiş EntityManagerFactory” nümunəsi uyğun gəlir. Məsələn, bunu edək:
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);
    }
}
Hörmətli, mövzumuz hazırdır. Bu hissəni buraxmaq istəməzdim , çünki... Növbəti fəsillər üçün mövzumuzun necə yarandığını anlamaq məsləhətdir.

Dəyişdirilə bilən davranışın tapılması

BigInteger tipli count sahəsinin inisializasiya yerini tutaq və orada kəsilmə nöqtələrini təyin edək ( BreakPoint ). İstədiyiniz sətirə daxil etdikdən sonra bunu Ctrl+F8 düymələrindən istifadə etməklə və ya Run -> Xətt Kəsmə Nöqtəsini dəyiş menyusu vasitəsilə etmək olar. Sonra əsas metodumuzu debugda işlədirik (Run -> Debug):
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 3
Bir az yöndəmsiz nümunədir, amma deyək ki, başlanğıcda sorğu boşluqlarının sayını dəyişmək istəyirik. Gördüyümüz kimi, bizim sqlQuery NativeQueryImpl-dir. klikləyin Ctrl+N, sinfin adını yazın və ona keçin. Beləliklə, bir sinfə getdiyimiz zaman bu sinfin yerləşdiyi yerə köçürüləcəyik və avtomatik sürüşdürməni yandıracağıq:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 4
Dərhal qeyd edək ki, Idea hazırda proqramın mənbə kodunu (mənbə kodu, yəni) haradan tapacağını bilmir. Buna görə də, o, nəzakətlə bizim üçün sinif faylının məzmununu dekompilyasiya etdi:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya başqalarının səhvlərini necə düzəltmək olar) - 5
Onu da qeyd edək ki, IntelliJ Idea pəncərəsinin başlığında Gradle-nin bizim üçün artefaktı harada saxladığı yazılır. İndi isə artefaktımızın yerləşdiyi yolu İdeyaya daxil edək:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 6
Komandadan istifadə edərək komanda xəttində bu qovluğa gedək cd way to каталогу. Dərhal qeyd edəcəm: mənbədən layihə qurmaq mümkündürsə, mənbədən qurmaq daha yaxşıdır. Məsələn, Hibernate mənbə kodu rəsmi internet saytında mövcuddur. İstədiyiniz versiya üçün onu seçmək və orada bütün dəyişiklikləri etmək və layihədə göstərilən tikinti skriptlərindən istifadə edərək yığmaq daha yaxşıdır. Mən məqalədə ən dəhşətli variantı təqdim edirəm - bir banka var, amma mənbə kodu yoxdur. Və 2 nömrəli qeyd: Gradle plaginlərdən istifadə edərək mənbə kodu əldə edə bilər. Ətraflı məlumat üçün Gradle istifadə edərək jar üçün javadocs və mənbələri necə yükləmək olar .

Dəyişiklik etmək

Dəyişdirdiyimiz sinifin hansı paketə uyğun olduğuna uyğun olaraq kataloq strukturunu yenidən yaratmalıyıq. Bu halda: mkdir org\hibernate\query\internal, bundan sonra biz bu kataloqda fayl yaradırıq NativeQueryImpl.java. İndi bu faylı açırıq və sinfin bütün məzmununu oradakı IDE-dən kopyalayırıq (İdeyanın bizim üçün dekompilyasiya etdiyi eyni). Lazımi xətləri dəyişdirin. Misal üçün:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 7
İndi faylı tərtib edək. Biz edirik: javac org\hibernate\query\internal\NativeQueryImpl.java. Vay, sadəcə götürüb səhvsiz tərtib edə bilməzsiniz. Biz çoxlu Simvol Tapılmır xətaları aldıq, çünki... dəyişkən sinif, IntelliJ Idea-nın adətən bizim üçün sinif yoluna əlavə etdiyi digər siniflərlə bağlıdır. IDE-lərimizin bütün faydalılığını hiss edirsinizmi? =) Yaxşı, özümüz əlavə edək, biz də edə bilərik. Yolları kopyalayaq:
  • [1] - hibernate-core-5.2.17.Final.jar
  • [2] - hibernate-jpa-2.1-api-1.0.0.Final.jar
Eynilə etdiyimiz kimi: “Xarici kitabxanalar”da “Layihə” görünüşündə biz tələb olunan bankanı tapırıq və üzərinə klikləyirik Ctrl+Shift+C. İndi isə aşağıdakı əmri yaradaq və icra edək: javac -cp [1];[2] org\hibernate\query\internal\NativeQueryImpl.java Nəticədə, jar faylında yenilənməli olan java faylının yanında yeni sinif faylları görünəcək:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 8
Hurray, indi jar yeniləməsini həyata keçirə bilərsiniz. Rəsmi materiallardan istifadə edə bilərik : jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class Open IntelliJ Idea, çox güman ki, faylları dəyişməyə imkan verməyəcək. Buna görə də, jar yeniləməsini həyata keçirməzdən əvvəl, çox güman ki, Idea-nı bağlamalı olacaqsınız və yeniləmədən sonra onu açın. Bundan sonra siz IDE-ni yenidən aça və dubuq-u yenidən işə sala bilərsiniz. IDE-nin yenidən işə salınması arasında fasilə nöqtələri sıfırlanmır. Beləliklə, proqramın icrası əvvəllər olduğu yerdə dayanacaq. Voila, dəyişikliklərimizin necə işlədiyini görürük:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 9
Əla. Ancaq burada sual yaranır - nəyə görə? Sadəcə ona görə ki, gradle bir layihə qurarkən asılılıqları və depolar blokunu təhlil edir. Gradle müəyyən bir yerdə yerləşən müəyyən bir qurma keşinə malikdir (bax: “ Qradl keşinin yerini necə təyin etmək olar? ” Əgər keşdə heç bir asılılıq yoxdursa, Gradle onu repozitoriyadan endirəcək. keşin özü, sonra Gradle düşünür ki, kitabxana keşdədir və heç nə çıxarmır.Lakin keşin hər hansı təmizlənməsi bizim dəyişikliklərimizin itməsinə səbəb olacaq.Bundan başqa, bizdən başqa heç kim gedib onları ala bilməz.Nə qədər narahatçılıq var , elə deyilmi? Nə etməli. Hmm, depodan endirmələr? Deməli, bizə üstünlüklər və şairələr olan depomuz lazımdır. Bu, növbəti addımdır.

Anbarın yerləşdirilməsi

Repozitorunuzu yerləşdirmək üçün müxtəlif pulsuz həllər var: onlardan biri Artifactory , digəri isə Apache Arxividir . Artifactory dəbli, qəşəng, müasir görünür, lakin bununla bağlı çətinlik çəkdim, artefaktları düzgün yerləşdirmək istəmədim və səhv maven metadata yaratdım. Buna görə də, gözlənilmədən mənim üçün Apache versiyası mənim üçün işlədi. O qədər də gözəl olmadığı ortaya çıxdı, amma etibarlı işləyir. Yükləmə səhifəsində Bağımsız versiyanı axtarın və paketdən çıxarın. Onların öz " Tez Başlanğıc "ı var. Başladıqdan sonra ünvana qədər gözləmək lazımdır http://127.0.0.1:8080/#repositorylist. Bundan sonra "Artifaktı yüklə" seçin:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya digər insanların səhvlərini necə düzəltmək olar) - 10
"Yükləməni Başlat" düyməsini və sonra "Faylları Saxla" düyməsini basın. Bundan sonra yaşıl müvəffəqiyyət mesajı görünəcək və artefakt "Gözdən keçir" bölməsində mövcud olacaq. Bu, jar və pom faylları üçün edilməlidir:
IntelliJ Idea: Dekompilyasiya, Kompilyasiya, Əvəzetmə (və ya başqalarının səhvlərini necə düzəltmək olar) - 11
Bu, pom faylında əlavə qışlama asılılıqlarının göstərildiyi ilə bağlıdır. Və yalnız 1 addımımız qalıb - tikinti skriptimizdə deponu göstərin:

repositories {
    jcenter()
    maven {
        url "http://127.0.0.1:8080/repository/internal/"
    }
}
Və buna görə qış yuxusumuzun versiyası belə olacaq: compile 'org.hibernate:hibernate-core:5.2.17.Final-JAVARUSH'. Hamısı budur, indi layihəmiz orijinaldan deyil, düzəliş etdiyimiz versiyadan istifadə edir.

Nəticə

Deyəsən tanış olduq. Ümid edirəm maraqlı oldu. Bu cür "hiylələr" nadir hallarda edilir, lakin birdən iş tələbləriniz istifadə etdiyiniz kitabxanaların təmin edə bilməyəcəyi şərtləri qoyursa, nə edəcəyinizi bilirsiniz. Bəli, bu şəkildə düzəldilə bilən bir neçə nümunə var:
  • Undertow adlı bir veb server var. Bir müddətə qədər proksi istifadə edərkən son istifadəçinin IP-sini öyrənməyə imkan verməyən bir səhv var idi.
  • Hal-hazırda, WildFly JPA müəyyən bir şəkildə idarə olunan bir an spesifikasiya tərəfindən nəzərə alınmadı, buna görə İstisnalar atıldı. Və konfiqurasiya edilə bilməzdi.
#Viaçeslav
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION