JavaRush /จาวาบล็อก /Random-TH /แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแ...
Viacheslav
ระดับ

แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น)

เผยแพร่ในกลุ่ม
“อย่าสร้างวงล้อขึ้นมาใหม่” เป็นหนึ่งในกฎหลักสำหรับการทำงานที่ประสบความสำเร็จและมีประสิทธิภาพ แต่จะทำยังไงเมื่อไม่อยากสร้างล้อของตัวเองขึ้นมาใหม่แต่พวงมาลัยของคนอื่นกลับบิดเบี้ยวและล้อเป็นรูปสี่เหลี่ยม? การตรวจสอบนี้มีวัตถุประสงค์เพื่อให้คำแนะนำโดยย่อเกี่ยวกับเทคนิคการซ่อมแซมไลบรารีของผู้อื่น “เป็นทางเลือกสุดท้าย” และวิธีการขยายสิ่งนี้ไปยังคอมพิวเตอร์ของคุณ
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 1

การแนะนำ

เราทุกคนใช้เครื่องมืออย่างใดอย่างหนึ่ง แต่บางครั้งเครื่องมือก็ไม่เหมาะสมหรือมีข้อผิดพลาด ด้วยคุณสมบัติของภาษา Java เราจึงสามารถแก้ไขพฤติกรรมของเครื่องมือในจุดที่เราต้องการได้ เป็นเรื่องดีเมื่อเรามีส่วนร่วมในโครงการและส่งคำขอดึงข้อมูล (คุณสามารถอ่านเพิ่มเติมได้ที่นี่: “ GitHub - การมีส่วนร่วมในโครงการ ”) แต่พวกเขาอาจจะไม่ได้รับการยอมรับในทันทีหรืออาจจะไม่ได้รับการยอมรับด้วยซ้ำ แต่สำหรับความต้องการของโครงการตอนนี้มีความจำเป็น ฉันหวังว่าบทความนี้จะแสดงเครื่องมือที่มีให้เราในฐานะนักพัฒนา เราจะต้องดำเนินการตามขั้นตอนต่อไปนี้ที่เราจะพูดถึง:
  • เตรียมตัวอย่างแอปพลิเคชันทดสอบ (โดยใช้ตัวอย่างโครงการ Hibernate)
  • การหาตำแหน่งที่เปลี่ยนแปลงได้
  • ทำการเปลี่ยนแปลง
  • กำลังปรับใช้พื้นที่เก็บข้อมูล
ขั้นตอนทั้งหมดด้านล่างนี้มีไว้สำหรับ Windows OS แต่จะมีแอนะล็อกสำหรับระบบ nix ดังนั้นคุณสามารถทำซ้ำได้หากจำเป็น

การเตรียมวิชา

ดังนั้นเราจึงต้องมีโครงการทดสอบ ไฮเบอร์เนตเหมาะสำหรับเรา เพราะ... มันคือ "มีสไตล์ ทันสมัย ​​ทันสมัย" ฉันจะไม่ลงรายละเอียดมากเกินไปเพราะ... บทความนี้ไม่เกี่ยวกับไฮเบอร์เนต เราจะทำทุกอย่างอย่างรวดเร็วและตรงประเด็น และเราก็จะใช้ระบบการสร้างเช่นเดียวกับนักพัฒนาที่เหมาะสม ตัวอย่างเช่น Gradle ก็เหมาะกับเราเช่นกันซึ่งจะต้องติดตั้งสำหรับบทความนี้ ( https://gradle.org/install/ ) ขั้นแรกเราต้องสร้างโครงการ Maven มีต้นแบบ สำหรับสิ่งนี้ และ Gradle มีปลั๊กอินพิเศษสำหรับสิ่งนี้: Gradle Init ดังนั้นให้เปิดบรรทัดคำสั่งในลักษณะที่คุณรู้จัก สร้างไดเร็กทอรีสำหรับโปรเจ็กต์ ไปที่ไดเร็กทอรีและรันคำสั่ง:

mkdir javarush 
cd javarush 
gradle init --type java-application
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 2
ก่อนที่จะนำเข้าโปรเจ็กต์ เรามาทำการเปลี่ยนแปลงกับไฟล์ที่อธิบายวิธีการสร้างก่อน ไฟล์นี้เรียกว่าสคริปต์บิลด์และมีชื่อว่า build.gradle ตั้งอยู่ในไดเร็กทอรีที่เราดำเนินการ gradle init ดังนั้นเราจึงเปิดมันขึ้นมา (เช่นใน Windows ด้วยคำสั่ง start build.gradle) เราพบบล็อก " การพึ่งพา " ที่นั่น เช่น การพึ่งพาอาศัยกัน ไหของบุคคลที่สามทั้งหมดที่เราจะใช้มีคำอธิบายอยู่ที่นี่ ตอนนี้เราต้องเข้าใจสิ่งที่จะอธิบายที่นี่ ไปที่เว็บไซต์ Hibernate ( http://hibernate.org/ ) เรามีความสนใจในHibernate ORM เราต้องการรุ่นล่าสุด ในเมนูด้านซ้ายมีส่วนย่อย "การเผยแพร่" เลือก “เสถียรล่าสุด” เลื่อนลงและค้นหา “การใช้งานหลัก (รวม JPA)” ก่อนหน้านี้จำเป็นต้องเชื่อมต่อการสนับสนุน JPA แยกกัน แต่ตอนนี้ทุกอย่างง่ายขึ้นและการพึ่งพาเพียงครั้งเดียวก็เพียงพอแล้ว เราจะต้องทำงานกับฐานข้อมูลโดยใช้ Hibernate ด้วย ในการทำเช่นนี้ลองใช้ตัวเลือกที่ง่ายที่สุด - ฐานข้อมูล H2 . ตัดสินใจแล้ว นี่คือการพึ่งพาของเรา:

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'
}
เยี่ยมมาก อะไรต่อไป? เราจำเป็นต้องกำหนดค่าไฮเบอร์เนต Hibernate มี " คู่มือเริ่มต้นใช้งาน " แต่มันโง่และเป็นอุปสรรคมากกว่าความช่วยเหลือ ดังนั้นเรามาดูตรงไปที่ “ User Guide ” เหมือนคนที่ใช่กันดีกว่า ในสารบัญเราเห็นส่วน “ Bootstrap ” ซึ่งแปลว่า “ Bootstrapping” สิ่งที่คุณต้องการ มีคำที่ชาญฉลาดเขียนไว้มากมาย แต่ประเด็นก็คือ ควรมีไดเร็กทอรี META-INF บน classpath และควรมีไฟล์ Peristence.xml ตามมาตรฐาน classpath มีไดเร็กทอรี "resources" ดังนั้นเราจึงสร้างไดเร็กทอรีที่ระบุ: mkdir src\main\resources\META-INF สร้างไฟล์ Peristence.xml ที่นั่นและเปิดมัน ในเอกสารประกอบมีตัวอย่าง “ตัวอย่าง 268 ไฟล์การกำหนดค่า META-INF/persistence.xml” ซึ่งเราจะนำเนื้อหาและแทรกลงในไฟล์ Persistence.xml จากนั้น เปิด IDE และนำเข้าโปรเจ็กต์ที่เราสร้างไว้ลงไป ตอนนี้เราต้องบันทึกบางอย่างลงในฐานข้อมูล นี่คือสิ่งที่เรียกว่าเอนทิตี เอนทิตีเป็นตัวแทนของบางสิ่งจากแบบจำลองโดเมนที่เรียกว่า และในสารบัญ ดูเถิด เราเห็น “ 2. รูปแบบโดเมน ” เราลงไปที่ข้อความและดูในบท “2.1 ประเภทการแมป” ตัวอย่างง่ายๆ ของเอนทิตี เรามาทำความเข้าใจกันให้สั้นลงหน่อย:
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;
    }
}
ตอนนี้เรามีคลาสที่แสดงถึงเอนทิตี กลับไปที่ Persistence.xml และแก้ไขที่เดียว: ในกรณีที่ระบุ เราจะ ระบุclassคลาสของเรา entity.Contactเยี่ยมมาก สิ่งที่เหลืออยู่คือการเปิดตัว กลับไปที่ บท Bootstrapกัน เนื่องจากเราไม่มีแอปพลิเคชันเซิร์ฟเวอร์ที่จะมอบสภาพแวดล้อม EE พิเศษให้กับเรา (เช่น สภาพแวดล้อมที่ใช้ลักษณะการทำงานของระบบบางอย่างสำหรับเรา) เราจึงทำงานในสภาพแวดล้อม SE สำหรับสิ่งนี้ เฉพาะตัวอย่าง “ตัวอย่าง 269. Application bootstrapped EntityManagerFactory” เท่านั้นที่เหมาะสำหรับเรา ตัวอย่างเช่น ลองทำสิ่งนี้:
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);
    }
}
ไชโย วิชาของเราพร้อมแล้ว ฉันไม่ต้องการที่จะละเว้นส่วนนี้เพราะ... สำหรับบทต่อไปนี้ ขอแนะนำให้ทำความเข้าใจว่าหัวข้อของเราเกิดขึ้นได้อย่างไร

ค้นหาพฤติกรรมที่ปรับเปลี่ยนได้

ลองใช้สถานที่เริ่มต้นของฟิลด์การนับประเภท BigInteger และตั้งค่าเบรกพอยต์ที่นั่น ( เบรกพอยต์ ) เมื่อแทรกบรรทัดที่ต้องการแล้ว สามารถทำได้โดยใช้ Ctrl+F8 หรือผ่านเมนู Run -> Toggle Line Breakpoint จากนั้นเราจะรันเมธอดหลักของเราในการดีบัก (Run -> Debug):
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 3
เป็นตัวอย่างที่ค่อนข้างงุ่มง่าม แต่สมมติว่าเราต้องการเปลี่ยนจำนวนพื้นที่การสืบค้นเมื่อเริ่มต้น ดังที่เราเห็น sqlQuery ของเราคือ NativeQueryImpl คลิกCtrl+Nเขียนชื่อชั้นเรียน และไปที่ชั้นเรียนนั้น เพื่อว่าเมื่อเราไปที่ชั้นเรียน เราจะถูกย้ายไปยังสถานที่ที่ชั้นเรียนนี้ตั้งอยู่และเปิดการเลื่อนอัตโนมัติ:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 4
ให้เราทราบทันทีว่าปัจจุบัน Idea ยังไม่รู้ว่าจะหาซอร์สโค้ดของโปรแกรมได้ที่ไหน (นั่นคือซอร์สโค้ด) ดังนั้นเธอกรุณาถอดรหัสเนื้อหาจากไฟล์คลาสให้เรา:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 5
โปรดทราบว่าในชื่อของหน้าต่าง IntelliJ Idea มีการเขียนโดยที่ Gradle บันทึกสิ่งประดิษฐ์ให้เรา ตอนนี้ มาดูเส้นทางที่สิ่งประดิษฐ์ของเราตั้งอยู่:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 6
ไปที่ไดเร็กทอรีนี้บนบรรทัดคำสั่งโดยใช้คำcd way to каталогуสั่ง ฉันจะจดบันทึกทันที: หากเป็นไปได้ที่จะสร้างโปรเจ็กต์จากแหล่งที่มา ก็ควรสร้างจากแหล่งที่มาจะดีกว่า ตัวอย่างเช่น ซอร์สโค้ด Hibernate มีอยู่ในเว็บไซต์อย่างเป็นทางการ จะดีกว่าถ้าเลือกเวอร์ชันที่ต้องการและทำการเปลี่ยนแปลงทั้งหมดที่นั่นและประกอบโดยใช้สคริปต์บิลด์ที่ระบุไว้ในโปรเจ็กต์ ฉันนำเสนอตัวเลือกที่แย่ที่สุดในบทความ - มีขวด แต่ไม่มีซอร์สโค้ด และหมายเหตุข้อที่ 2: Gradle สามารถรับซอร์สโค้ดได้โดยใช้ปลั๊กอิน ดู วิธีดาวน์โหลด javadocs และแหล่งที่มาสำหรับ jar โดยใช้ Gradleเพื่อดูรายละเอียด

ทำการเปลี่ยนแปลง

เราจำเป็นต้องสร้างโครงสร้างไดเร็กทอรีใหม่ตามแพ็คเกจที่คลาสที่เรากำลังเปลี่ยนแปลงอยู่ ในกรณีนี้: mkdir org\hibernate\query\internalหลังจากนั้นเราจะสร้างไฟล์ในไดเร็กทอรีNativeQueryImpl.javaนี้ ตอนนี้เราเปิดไฟล์นี้และคัดลอกเนื้อหาทั้งหมดของคลาสจาก IDE ที่นั่น (ไฟล์เดียวกับที่ Idea ถอดรหัสให้เรา) เปลี่ยนบรรทัดที่จำเป็น ตัวอย่างเช่น:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 7
ตอนนี้เรามารวบรวมไฟล์กัน พวกเราทำ: javac org\hibernate\query\internal\NativeQueryImpl.java. ว้าว คุณไม่สามารถนำไปใช้และคอมไพล์โดยไม่มีข้อผิดพลาดได้ เราได้รับข้อผิดพลาดไม่พบสัญลักษณ์มากมาย เนื่องจาก... คลาสที่ไม่แน่นอนนั้นเชื่อมโยงกับคลาสอื่น ซึ่ง IntelliJ Idea มักจะเพิ่มให้กับ classpath สำหรับเรา คุณรู้สึกถึงประโยชน์ทั้งหมดของ IDE ของเราหรือไม่? =) เอาล่ะเติมเองเราก็ทำได้ มาคัดลอกเส้นทางสำหรับ:
  • [1] - hibernate-core-5.2.17.Final.jar
  • [2] - ไฮเบอร์เนต-jpa-2.1-api-1.0.0.Final.jar
เช่นเดียวกับที่เราทำ: ในมุมมอง "โครงการ" ใน "ไลบรารีภายนอก" เราจะพบ jar ที่ต้องการแล้วCtrl+Shift+Cคลิก ตอนนี้เรามาสร้างและดำเนินการคำสั่งต่อไปนี้: javac -cp [1];[2] org\hibernate\query\internal\NativeQueryImpl.java ดังนั้นไฟล์คลาสใหม่จะปรากฏถัดจากไฟล์ java ซึ่งจำเป็นต้องได้รับการอัปเดตในไฟล์ jar:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 8
ไชโย ตอนนี้คุณสามารถอัปเดต jar ได้แล้ว เราได้รับคำแนะนำจากเอกสารอย่างเป็นทางการ : jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class Open IntelliJ Idea มักจะไม่อนุญาตให้คุณเปลี่ยนไฟล์ ดังนั้น ก่อนดำเนินการอัปเดต Jar คุณมักจะต้องปิด Idea และหลังจากอัปเดต ให้เปิดขึ้น หลังจากนี้ คุณสามารถเปิด IDE อีกครั้งและเรียกใช้ dubug อีกครั้ง จุดพักจะไม่ถูกรีเซ็ตระหว่างการรีสตาร์ท IDE ดังนั้นการทำงานของโปรแกรมจะหยุดลงจากเดิม เอาล่ะ เราจะเห็นว่าการเปลี่ยนแปลงของเราทำงานอย่างไร:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 9
ยอดเยี่ยม. แต่คำถามก็เกิดขึ้น - เพราะอะไร? เพียงเพราะว่าเมื่อ gradle สร้างโปรเจ็กต์ มันจะวิเคราะห์การพึ่งพาและบล็อกที่เก็บข้อมูล Gradle มี build cache บางตัวซึ่งอยู่ในตำแหน่งที่แน่นอน (ดู “ วิธีตั้งค่าตำแหน่งแคช gradle ” หากไม่มีการอ้างอิงในแคช Gradle จะดาวน์โหลดจาก repository เนื่องจากเราเปลี่ยน jar ใน cache เองแล้ว Gradle คิดว่าไลบรารี่อยู่ใน cache และไม่ได้ปั๊มอะไรออกไป แต่การล้าง cache ใด ๆ จะทำให้การเปลี่ยนแปลงของเราหายไป แถมไม่มีใครนอกจากเราไปเอาได้เลย ไม่สะดวกขนาดไหน ใช่ไหม จะทำอย่างไร อืม ดาวน์โหลดจากพื้นที่เก็บข้อมูล ดังนั้น เราต้องการพื้นที่เก็บข้อมูลของเราซึ่งมีการตั้งค่าและนักกวี นี่คือขั้นตอนต่อไป

กำลังปรับใช้พื้นที่เก็บข้อมูล

มีโซลูชันฟรีต่างๆ สำหรับการปรับใช้พื้นที่เก็บข้อมูลของคุณ: หนึ่งในนั้นคือArtifactoryและอีกวิธีคือApache Archive Artifactory ดูทันสมัย ​​มีสไตล์ ทันสมัย ​​แต่ฉันมีปัญหากับมัน ฉันไม่ต้องการวางสิ่งประดิษฐ์อย่างถูกต้อง และสร้างเมตาดาต้า maven ที่ผิดพลาด ดังนั้นเวอร์ชัน Apache จึงใช้งานได้สำหรับฉันโดยไม่คาดคิด มันกลับกลายเป็นว่าไม่สวยงามนัก แต่ก็ใช้งานได้อย่างน่าเชื่อถือ ใน หน้า ดาวน์โหลดให้มองหาเวอร์ชันสแตนด์อโลนแล้วแกะออก พวกเขามี " Quick Start " ของตัวเอง หลังจากเปิดตัวคุณจะต้องรอจนกว่าจะถึงที่http://127.0.0.1:8080/#repositorylistอยู่ หลังจากนั้น เลือก "อัปโหลดสิ่งประดิษฐ์":
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 10
คลิก "เริ่มอัปโหลด" จากนั้นคลิก "บันทึกไฟล์" หลังจากนี้ ข้อความแสดงความสำเร็จสีเขียวจะปรากฏขึ้น และอาร์ติแฟกต์จะพร้อมใช้งานในส่วน "เรียกดู" สิ่งนี้ควรทำสำหรับไฟล์ jar และ pom:
แนวคิด IntelliJ: การคอมไพล์ การรวบรวม การทดแทน (หรือวิธีแก้ไขข้อผิดพลาดของผู้อื่น) - 11
นี่เป็นเพราะความจริงที่ว่ามีการระบุการพึ่งพาไฮเบอร์เนตเพิ่มเติมในไฟล์ pom และเราเหลืออีกเพียง 1 ขั้นตอนเท่านั้น - ระบุพื้นที่เก็บข้อมูลในสคริปต์บิลด์ของเรา:

repositories {
    jcenter()
    maven {
        url "http://127.0.0.1:8080/repository/internal/"
    }
}
และตามนั้น เวอร์ชันจำศีลของเราจะกลายเป็น: compile 'org.hibernate:hibernate-core:5.2.17.Final-JAVARUSH'. เพียงเท่านี้ ตอนนี้โปรเจ็กต์ของเราใช้เวอร์ชันที่เราแก้ไข ไม่ใช่เวอร์ชันดั้งเดิม

บทสรุป

ดูเหมือนเราจะรู้จักกันแล้ว.. ฉันหวังว่ามันจะน่าสนใจ “เคล็ดลับ” ดังกล่าวไม่ค่อยเกิดขึ้น แต่ถ้าจู่ๆ ความต้องการทางธุรกิจของคุณกำหนดเงื่อนไขว่าห้องสมุดที่คุณใช้ไม่สามารถตอบสนองได้ คุณก็รู้ว่าต้องทำอย่างไร และนี่คือตัวอย่างบางส่วนที่สามารถแก้ไขได้ด้วยวิธีนี้:
  • มีเว็บเซิร์ฟเวอร์ชื่อ Undertow จนกระทั่งถึงช่วงหนึ่ง มีข้อผิดพลาดที่เมื่อใช้พรอกซี ไม่อนุญาตให้เราค้นหา IP ของผู้ใช้ปลายทาง
  • ในขณะนี้ WildFly JPA จัดการด้วยวิธีใดวิธีหนึ่งซึ่งไม่ได้คำนึงถึงข้อกำหนด เนื่องจากข้อยกเว้นนี้ถูกส่งออกไป และมันกำหนดค่าไม่ได้
#เวียเชสลาฟ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION