JavaRush /Java Blog /Random-TL /IntelliJ Idea: Decompilation, Compilation, Substitution (...

IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao)

Nai-publish sa grupo
"Huwag muling likhain ang gulong" ay isa sa mga pangunahing panuntunan para sa matagumpay at mahusay na trabaho. Ngunit ano ang gagawin kapag ayaw mong muling likhain ang iyong sariling gulong, ngunit ang manibela ng ibang tao ay lumabas na baluktot at ang mga gulong ay parisukat? Ang pagsusuri na ito ay nilayon na magbigay ng maikling panimula hangga't maaari sa pamamaraan ng pag-aayos ng mga aklatan ng ibang tao "bilang huling paraan" at kung paano ito i-extend sa iyong computer.
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 1

Panimula

Lahat tayo ay gumagamit ng isang tool o iba pa. Ngunit kung minsan ang mga tool ay hindi ganap na angkop o may mga error. Salamat sa mga tampok ng wikang Java, maaari naming itama ang pag-uugali ng mga tool kung saan namin ito kailangan. Maganda kapag nag-aambag kami sa mga proyekto at nagpapadala ng mga pull request (maaari kang magbasa ng higit pa dito: " GitHub - Contributing to projects ”). Ngunit maaaring hindi sila matanggap kaagad, o maaaring hindi sila matanggap. Ngunit para sa mga pangangailangan ng proyekto ito ay kinakailangan ngayon. At dito, umaasa ako, ipapakita ng artikulong ito ang mga tool na magagamit sa amin bilang mga developer. Kakailanganin nating gawin ang mga sumusunod na hakbang na pag-uusapan natin:
  • Maghanda ng isang pagsubok na aplikasyon halimbawa (gamit ang halimbawa ng isang Hibernate na proyekto)
  • Paghahanap ng nababagong lokasyon
  • Gumagawa ng pagbabago
  • Pag-deploy ng repositoryo
Ang lahat ng mga hakbang sa ibaba ay ibinigay para sa Windows OS, ngunit may mga analogue para sa nix system. Kaya maaari mong ulitin ang mga ito kung kinakailangan.

Paghahanda ng Paksa

Kaya, kailangan namin ng isang pagsubok na proyekto. Tamang-tama para sa amin ang hibernate, dahil... ito ay "naka-istilong, sunod sa moda, moderno." Hindi ko na idedetalye masyado, kasi... Ang artikulo ay hindi tungkol sa Hibernate. Gagawin namin ang lahat nang mabilis at sa punto. At kami, tulad ng mga wastong developer, ay gagamit ng build system. Halimbawa, ang Gradle ay angkop din para sa amin, na dapat na mai-install para sa artikulong ito ( https://gradle.org/install/ ). Una, kailangan nating gumawa ng isang proyekto. May mga archetype si Maven para dito , at may espesyal na plugin ang Gradle para dito: Gradle Init . Kaya, buksan ang command line sa anumang paraan na alam mo. Lumikha ng isang direktoryo para sa proyekto, pumunta dito at isagawa ang utos:

mkdir javarush 
cd javarush 
gradle init --type java-application
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 2
Bago i-import ang proyekto, gumawa tayo ng ilang pagbabago sa file na naglalarawan kung paano bumuo. Ang file na ito ay tinatawag na build script at pinangalanang build.gradle. Ito ay matatagpuan sa direktoryo kung saan namin pinaandar ang gradle init. Samakatuwid, binubuksan lang namin ito (halimbawa, sa Windows gamit ang start build.gradle command). Nahanap namin ang block na " mga dependency " doon, i.e. dependencies. Ang lahat ng mga third-party na garapon na aming gagamitin ay inilarawan dito. Ngayon ay kailangan nating maunawaan kung ano ang ilalarawan dito. Pumunta tayo sa website ng Hibernate ( http://hibernate.org/ ). Interesado kami sa Hibernate ORM . Kailangan namin ang pinakabagong release. Sa menu sa kaliwa mayroong isang subsection na "Mga Paglabas". Piliin ang "pinakabagong matatag". Mag-scroll pababa at hanapin ang “Core na pagpapatupad (kasama ang JPA)”. Noong nakaraan, kinakailangan upang ikonekta ang suporta ng JPA nang hiwalay, ngunit ngayon ang lahat ay naging mas simple at isang dependency lamang ang sapat. Kakailanganin din nating magtrabaho kasama ang database gamit ang Hibernate. Upang gawin ito, gawin natin ang pinakasimpleng opsyon - H2 Database . Ang pagpili ay ginawa, narito ang aming mga dependencies:

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'
}
Mahusay, ano ang susunod? Kailangan nating i-configure ang Hibernate. Ang hibernate ay may " Gabay sa Pagsisimula ", ngunit ito ay hangal at higit pa sa isang hadlang kaysa isang tulong. Samakatuwid, dumiretso tayo sa " Gabay sa Gumagamit " tulad ng mga tamang tao. Sa talaan ng mga nilalaman nakikita namin ang seksyong " Bootstrap ", na isinasalin bilang "Bootstrapping". Kung ano lang ang kailangan mo. Mayroong maraming matalinong mga salita na nakasulat doon, ngunit ang punto ay dapat mayroong isang direktoryo ng META-INF sa classpath, at dapat mayroong isang persistence.xml file. Ayon sa pamantayan, ang classpath ay naglalaman ng direktoryo ng "mga mapagkukunan". Samakatuwid, nilikha namin ang tinukoy na direktoryo: mkdir src\main\resources\META-INF Lumikha ng persistence.xml file doon at buksan ito. Doon sa dokumentasyon mayroong isang halimbawang "Halimbawa 268. META-INF/persistence.xml configuration file" kung saan kukunin namin ang mga nilalaman at ipasok ito sa persistence.xml file. Susunod, ilunsad ang IDE at i-import ang aming ginawang proyekto dito. Ngayon kailangan nating mag-save ng isang bagay sa database. Ito ay isang bagay na tinatawag na entity. Ang mga entity ay kumakatawan sa isang bagay mula sa tinatawag na modelo ng domain. At sa talaan ng mga nilalaman, narito at masdan, makikita natin ang " 2. Modelo ng Domain ". Bumaba tayo sa teksto at makikita sa kabanata na "2.1. Mga uri ng pagmamapa" ang isang simpleng halimbawa ng isang entity. Dalhin natin ito sa ating sarili, paikliin ito ng kaunti:
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;
    }
}
Ngayon ay mayroon kaming isang klase na kumakatawan sa isang entity. Bumalik tayo sa persistence.xml at itama ang isang lugar doon: Kung saan ipinahiwatig, classipahiwatig namin ang aming klase entity.Contact. Mahusay, ang natitira na lang ay ilunsad. Balik tayo sa Bootstrap chapter . Dahil wala kaming application server na magbibigay sa amin ng isang espesyal na EE environment (ibig sabihin, isang environment na nagpapatupad ng ilang partikular na gawi ng system para sa amin), nagtatrabaho kami sa isang SE environment. Para dito, tanging ang halimbawang "Halimbawa 269. Application bootstrapped EntityManagerFactory" ang angkop para sa amin. Halimbawa, gawin natin ito:
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);
    }
}
Hurray, ready na ang subject natin. Hindi ko nais na alisin ang bahaging ito , dahil... Para sa susunod na mga kabanata, ipinapayong maunawaan kung paano naging paksa ang ating paksa.

Paghahanap ng Nababagong Gawi

Palitan natin ang pagsisimula ng field ng bilang ng uri ng BigInteger at magtakda ng mga breakpoint doon ( BreakPoint ). Ang pagpasok sa nais na linya, maaari itong gawin gamit ang Ctrl+F8 o sa pamamagitan ng menu Run -> Toggle Line Breakpoint. Pagkatapos ay pinapatakbo namin ang aming pangunahing pamamaraan sa debug (Run -> Debug):
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 3
Medyo clumsy na halimbawa, pero sabihin nating gusto nating baguhin ang bilang ng mga query space sa startup. Tulad ng nakikita natin, ang aming sqlQuery ay NativeQueryImpl. I-click ang Ctrl+N, isulat ang pangalan ng klase, at pumunta dito. Upang kapag pumunta tayo sa isang klase, ililipat tayo sa lugar kung saan matatagpuan ang klase na ito at i-on ang autoscroll:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 4
Tandaan natin kaagad na hindi alam ng Idea sa kasalukuyan kung saan mahahanap ang source code ng programa (source code, iyon ay). Samakatuwid, magiliw niyang i-decompile ang mga nilalaman mula sa file ng klase para sa amin:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 5
Tandaan din na sa pamagat ng IntelliJ Idea window ito ay nakasulat kung saan ini-save ni Gradle ang artifact para sa amin. Ngayon, makuha natin sa Idea ang landas kung saan matatagpuan ang ating artifact:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 6
Pumunta tayo sa direktoryo na ito sa command line gamit ang command cd way to каталогу. Gagawa ako kaagad ng tala: kung posible na bumuo ng isang proyekto mula sa pinagmulan, mas mahusay na bumuo mula sa pinagmulan. Halimbawa, available ang Hibernate source code sa opisyal na website. Mas mainam na kunin ito para sa nais na bersyon at gawin ang lahat ng mga pagbabago doon at i-assemble gamit ang mga build script na tinukoy sa proyekto. Ipinakita ko sa artikulo ang pinaka-kahila-hilakbot na pagpipilian - mayroong isang garapon, ngunit walang source code. At tandaan bilang 2: Maaaring makuha ni Gradle ang source code gamit ang mga plugin. Tingnan ang Paano mag-download ng javadocs at mga source para sa jar gamit ang Gradle para sa mga detalye .

Gumagawa ng pagbabago

Kailangan nating muling likhain ang istraktura ng direktoryo alinsunod sa kung saang pakete naroroon ang klase na pinapalitan natin. Sa kasong ito: mkdir org\hibernate\query\internal, pagkatapos ay lumikha kami ng isang file sa direktoryong ito NativeQueryImpl.java. Ngayon binuksan namin ang file na ito at kinopya ang lahat ng mga nilalaman ng klase mula sa IDE doon (ang parehong na-decompiled ng Idea para sa amin). Baguhin ang mga kinakailangang linya. Halimbawa:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 7
Ngayon, i-compile natin ang file. Ginagawa namin: javac org\hibernate\query\internal\NativeQueryImpl.java. Wow, hindi mo ito basta-basta kunin at i-compile nang walang mga error. Nakatanggap kami ng maraming error sa Cannot Find Symbol, dahil... ang nababagong klase ay nakatali sa ibang mga klase, na karaniwang idinaragdag ng IntelliJ Idea sa classpath para sa amin. Nararamdaman mo ba ang lahat ng pagiging kapaki-pakinabang ng aming mga IDE? =) Well, dagdagan natin sarili natin, kaya rin natin. Gayahin natin ang mga landas para sa:
  • [1] - hibernate-core-5.2.17.Final.jar
  • [2] - hibernate-jpa-2.1-api-1.0.0.Final.jar
Tulad ng ginawa namin: Sa view na "Proyekto" sa "Mga panlabas na aklatan" makikita namin ang kinakailangang jar at i-click ang Ctrl+Shift+C. Ngayon, gawin natin at isagawa ang sumusunod na command: javac -cp [1];[2] org\hibernate\query\internal\NativeQueryImpl.java Bilang resulta, lalabas ang mga bagong class file sa tabi ng java file, na kailangang i-update sa jar file:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 8
Hurray, maaari ka na ngayong magsagawa ng jar update. Maaari tayong magabayan ng mga opisyal na materyales : jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class Ang Open IntelliJ Idea ay malamang na hindi ka papayagan na magpalit ng mga file. Samakatuwid, bago isagawa ang pag-update ng garapon, malamang na kailangan mong isara ang Ideya, at pagkatapos ng pag-update, buksan ito. Pagkatapos nito, maaari mong muling buksan ang IDE at patakbuhin muli ang dubug. Ang mga Break Point ay hindi na-reset sa pagitan ng mga pag-restart ng IDE. Samakatuwid, ang pagpapatupad ng programa ay titigil kung saan ito dati. Voila, nakikita namin kung paano gumagana ang aming mga pagbabago:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 9
Malaki. Ngunit narito ang tanong ay lumitaw - dahil sa ano? Dahil lang sa katotohanan na kapag bumuo si gradle ng isang proyekto, sinusuri nito ang mga dependencies at block ng mga repositoryo. Ang Gradle ay may partikular na build cache, na matatagpuan sa isang partikular na lokasyon (tingnan ang " Paano itakda ang lokasyon ng cache ng gradle? " Kung walang dependency sa cache, ida-download ito ng Gradle mula sa repository. Dahil binago namin ang jar sa cache mismo, pagkatapos ay iniisip ni Gradle na ang library ay nasa cache at hindi naglalabas ng anuman. Ngunit ang anumang pag-clear ng cache ay hahantong sa pagkawala ng aming mga pagbabago. At saka, walang sinuman maliban sa amin ang maaaring pumunta at kunin ang mga ito. Gaano karaming abala , di ba? Ano ang gagawin. Hmm, mga download mula sa repositoryo? Kaya kailangan namin ang aming repository, na may mga kagustuhan at poetesses. Ito ang susunod na hakbang.

Pag-deploy ng repositoryo

Mayroong iba't ibang mga libreng solusyon para sa pag-deploy ng iyong repository: isa sa mga ito ay Artifactory , at ang isa ay Apache Archive . Ang artifactory ay mukhang sunod sa moda, naka-istilong, moderno, ngunit nahirapan ako dito, hindi ko nais na maglagay ng mga artifact nang tama at bumuo ng maling maven metadata. Samakatuwid, sa hindi inaasahan para sa aking sarili, ang bersyon ng Apache ay nagtrabaho para sa akin. Ito ay naging hindi napakaganda, ngunit ito ay gumagana nang mapagkakatiwalaan. Sa pahina ng pag-download , hanapin ang Standalone na bersyon at i-unpack ito. Mayroon silang sariling " Mabilis na Pagsisimula ". Pagkatapos ilunsad, kailangan mong maghintay hanggang sa address http://127.0.0.1:8080/#repositorylist. Pagkatapos nito, piliin ang "Mag-upload ng Artifact":
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 10
I-click ang "Start Upload", at pagkatapos ay "Save Files". Pagkatapos nito, lalabas ang isang berdeng mensahe ng tagumpay at magiging available ang artifact sa seksyong "Browse". Dapat itong gawin para sa mga jar at pom file:
IntelliJ Idea: Decompilation, Compilation, Substitution (o kung paano itama ang mga pagkakamali ng ibang tao) - 11
Ito ay dahil sa ang katunayan na ang mga karagdagang hibernate dependencies ay tinukoy sa pom file. At mayroon na lang kaming 1 hakbang na natitira - tukuyin ang repository sa aming build script:

repositories {
    jcenter()
    maven {
        url "http://127.0.0.1:8080/repository/internal/"
    }
}
At, nang naaayon, ang bersyon ng aming hibernate ay magiging: compile 'org.hibernate:hibernate-core:5.2.17.Final-JAVARUSH'. Iyon lang, ngayon ginagamit ng aming proyekto ang bersyon na itinama namin, at hindi ang orihinal.

Konklusyon

Parang nagkakilala na kami. Sana naging kawili-wili ito. Ang ganitong mga "panlilinlang" ay bihirang gawin, ngunit kung biglang ang iyong mga kinakailangan sa negosyo ay nagtatakda ng mga kondisyon na ang mga aklatan na iyong ginagamit ay hindi matugunan, alam mo kung ano ang gagawin. At oo, narito ang ilang mga halimbawa na maaaring itama sa ganitong paraan:
  • Mayroong isang web server na tinatawag na Undertow. Hanggang sa ilang panahon, nagkaroon ng bug na, kapag gumagamit ng proxy, hindi namin pinayagan na malaman ang IP ng end user.
  • Sa ngayon, pinangasiwaan ng WildFly JPA sa isang tiyak na paraan ang isang sandali na hindi isinasaalang-alang ng mga detalye, dahil dito ang mga Exception ay itinapon. At hindi ito na-configure.
#Viacheslav
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION