JavaRush /בלוג Java /Random-HE /רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעוי...
Viacheslav
רָמָה

רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים)

פורסם בקבוצה
"אל תמציא את הגלגל מחדש" הוא אחד הכללים העיקריים לעבודה מוצלחת ויעילה. אבל מה לעשות כשאתה לא רוצה להמציא את הגלגל שלך מחדש, אבל ההגה של מישהו אחר מתגלה כעקום והגלגלים מרובעים? סקירה זו נועדה לספק מבוא קצר ככל האפשר לטכניקה של תיקון ספריות של אנשים אחרים "כמוצא אחרון" וכיצד להרחיב זאת למחשב שלך.
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 1

מבוא

כולנו משתמשים בכלי כזה או אחר. אבל לפעמים הכלים לא לגמרי מתאימים או שיש להם שגיאות. הודות לתכונות של שפת Java, אנו יכולים לתקן את התנהגות הכלים היכן שאנו זקוקים לה. זה טוב כשאנחנו תורמים לפרויקטים ושולחים בקשות משיכה (תוכלו לקרוא עוד כאן: " GitHub - תרומה לפרויקטים "). אבל אולי לא יתקבלו מיד, ואולי אפילו לא יתקבלו. אבל לצרכי הפרויקט זה נחוץ עכשיו. והנה, אני מקווה, מאמר זה יראה את הכלים העומדים לרשותנו כמפתחים. נצטרך לבצע את השלבים הבאים עליהם נדבר:
  • הכן יישום בדיקה למשל (באמצעות דוגמה של פרויקט Hibernate)
  • מציאת מיקום ניתן לשינוי
  • עושים שינוי
  • פריסת המאגר
כל השלבים שלהלן ניתנים עבור מערכת ההפעלה Windows, אך יש להם אנלוגים עבור מערכות nix. אז אתה יכול לחזור עליהם במידת הצורך.

הכנת הנושא

אז, אנחנו צריכים פרויקט מבחן. Hibernate הוא אידיאלי עבורנו, כי... זה "מסוגנן, אופנתי, מודרני". אני לא אפרט יותר מדי, כי... המאמר אינו עוסק ב-Hibernate. נעשה הכל במהירות ולעניין. ואנחנו, כמו מפתחים נכונים, נשתמש במערכת הבנייה. לדוגמא, גם Gradle מתאים לנו, אותו יש להתקין עבור מאמר זה ( https://gradle.org/install/ ). ראשית, עלינו ליצור פרויקט. ל-Maven יש ארכיטיפים עבור זה , ול-Gradle יש תוסף מיוחד לכך: Gradle Init . אז, פתח את שורת הפקודה בכל דרך המוכרת לך. צור ספרייה עבור הפרויקט, עבור אליה והפעל את הפקודה:

mkdir javarush 
cd javarush 
gradle init --type java-application
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 2
לפני ייבוא ​​הפרויקט, בואו נעשה כמה שינויים בקובץ שמתאר כיצד לבנות. קובץ זה נקרא סקריפט build והוא נקרא build.gradle. הוא ממוקם בספרייה שבה ביצענו gradle init. לכן, אנחנו פשוט פותחים אותו (לדוגמה, ב-Windows עם הפקודה start build.gradle). אנו מוצאים שם את גוש ה"תלות ", כלומר. תלות. כל הצנצנות של צד שלישי בהן נשתמש מתוארות כאן. עכשיו אנחנו צריכים להבין מה לתאר כאן. בואו נעבור לאתר Hibernate ( http://hibernate.org/ ). אנו מעוניינים ב- Hibernate ORM . אנחנו צריכים את המהדורה האחרונה. בתפריט בצד שמאל יש סעיף משנה "שחרורים". בחר "יציב אחרון". גלול מטה ומצא "יישום ליבה (כולל JPA)". בעבר היה צורך לחבר את תמיכת JPA בנפרד, אך כעת הכל הפך לפשוט יותר ומספיק רק תלות אחת. נצטרך גם לעבוד עם מסד הנתונים באמצעות Hibernate. כדי לעשות זאת, ניקח את האפשרות הפשוטה ביותר - H2 Database . הבחירה נעשית, הנה התלות שלנו:

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. ל-Hibernate יש " מדריך לתחילת העבודה ", אבל הוא טיפשי ויותר מפריע מאשר עוזר. לכן, בואו נלך ישר ל"מדריך למשתמש " כמו האנשים הנכונים. בתוכן העניינים אנו רואים את הסעיף " Bootstrap ", שמתורגם כ"Bootstrapping". בדיוק מה שאתה צריך. יש הרבה מילים חכמות שנכתבו שם, אבל הנקודה היא שצריכה להיות ספריית META-INF ב-classpath, וצריכה להיות קובץ persistence.xml. לפי התקן, ה-classpath מכיל את ספריית "resources". לכן, אנו יוצרים את הספרייה שצוינה: mkdir src\main\resources\META-INF צור שם את הקובץ persistence.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 bootstraped 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 ונקבע שם נקודות עצירה ( BreakPoint ). לאחר הוספה על השורה הרצויה, ניתן לעשות זאת באמצעות Ctrl+F8 או דרך התפריט Run -> Toggle Line Breakpoint. לאחר מכן אנו מפעילים את השיטה העיקרית שלנו ב-debug (Run -> Debug):
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 3
דוגמה קצת מגושמת, אבל נניח שאנחנו רוצים לשנות את מספר רווחי השאילתה בעת ההפעלה. כפי שאנו יכולים לראות, sqlQuery שלנו הוא NativeQueryImpl. לחץ על Ctrl+N, כתוב את שם הכיתה ועבור אליה. כך שכאשר נלך לשיעור, נעביר אותנו למקום בו ממוקמת השיעור הזה ונפעיל את האוטוסקרול:
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 4
נציין מיד ש-Idea לא יודע כרגע היכן למצוא את קוד המקור של התוכנית (קוד מקור, כלומר). לכן, היא בחביבות פירקה עבורנו את התוכן מקובץ הכיתה:
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 5
שימו לב גם שבכותרת של חלון IntelliJ Idea כתוב היכן Gradle שומר עבורנו את החפץ. עכשיו, בואו נבין את הנתיב שבו נמצא החפץ שלנו:
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 6
בוא נלך לספרייה זו בשורת הפקודה באמצעות הפקודה cd way to каталогу. אני אציין מיד: אם אפשר לבנות פרויקט ממקור, עדיף לבנות ממקור. לדוגמה, קוד המקור Hibernate זמין באתר הרשמי. עדיף להרים אותו לגרסה הרצויה ולבצע שם את כל השינויים ולהרכיב באמצעות סקריפטים של ה-build המצוינים בפרויקט. אני מציג במאמר את האפשרות הנוראה ביותר - יש צנצנת, אבל אין קוד מקור. והערה מספר 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 לנתיב הכיתה עבורנו. האם אתה מרגיש את כל התועלת של ה-IDEs שלנו? =) ובכן, בואו נוסיף את זה בעצמנו, גם אנחנו יכולים לעשות את זה. בואו נעתיק את הנתיבים עבור:
  • [1] - hibernate-core-5.2.17.Final.jar
  • [2] - hibernate-jpa-2.1-api-1.0.0.Final.jar
בדיוק כמו שעשינו: בתצוגת "פרויקט" ב"ספריות חיצוניות" אנו מוצאים את הצנצנת הנדרשת ולוחצים Ctrl+Shift+C. כעת בואו ניצור ונבצע את הפקודה הבאה: javac -cp [1];[2] org\hibernate\query\internal\NativeQueryImpl.java כתוצאה מכך, קבצי מחלקה חדשים יופיעו ליד קובץ ה-Java, אותם יש לעדכן בקובץ jar:
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 8
היי, עכשיו אתה יכול לבצע עדכון צנצנת. אנו יכולים להיות מודרכים על ידי חומרים רשמיים : jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class Open IntelliJ Idea סביר להניח שלא יאפשר לך לשנות קבצים. לכן, לפני ביצוע עדכון הצנצנת, סביר להניח שתצטרכו לסגור את Idea, ולאחר העדכון לפתוח אותה. לאחר מכן, אתה יכול לפתוח מחדש את ה-IDE ולהפעיל שוב dubug. נקודות השבירה אינן מתאפסות בין הפעלה מחדש של IDE. לכן, הפעלת התוכנית תיעצר במקום שהיה קודם. וואלה, אנחנו רואים איך השינויים שלנו עובדים:
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 9
גדול. אבל כאן נשאלת השאלה - בשל מה? פשוט בשל העובדה שכאשר Gradle בונה פרויקט, הוא מנתח את גוש התלות והמאגרים. ל-Gradle יש מטמון בנייה מסוים, שנמצא במיקום מסוים (ראה " איך להגדיר את מיקום המטמון של Gradle? " אם אין תלות ב-Cache, אז Gradle יוריד אותו מהמאגר. מכיוון ששינינו את ה-jar ב- המטמון עצמו, ואז גרדל חושב שהספרייה נמצאת במטמון ולא שואבת כלום. אבל כל ניקוי של המטמון יוביל לאיבוד השינויים שלנו. בנוסף, אף אחד מלבדנו לא יכול פשוט ללכת לקחת אותם. כמה אי נוחות , לא? מה לעשות. הממ, הורדות מהמאגר? אז אנחנו צריכים את המאגר שלנו, עם העדפות ומשוררות. זה השלב הבא.

פריסת המאגר

ישנם פתרונות חינמיים שונים לפריסת המאגר שלך: אחד מהם הוא Artifactory , והשני הוא Apache Archive . Artifactory נראה אופנתי, מסוגנן, מודרני, אבל היו לי קשיים עם זה, לא רציתי למקם חפצים בצורה נכונה ויצרתי מטא-נתונים שגויים. לכן, באופן בלתי צפוי עבורי, גרסת האפאצ'י עבדה עבורי. התברר שזה לא כל כך יפה, אבל זה עובד בצורה אמינה. בדף ההורדה , חפש את הגרסה העצמאית ופרק אותה. יש להם " התחלה מהירה " משלהם. לאחר ההשקה, עליך לחכות עד הכתובת http://127.0.0.1:8080/#repositorylist. לאחר מכן, בחר "העלה חפץ":
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 10
לחץ על "התחל העלאה" ולאחר מכן על "שמור קבצים". לאחר מכן, תופיע הודעת הצלחה ירוקה והחפץ יהפוך לזמין בקטע "עיון". זה צריך להיעשות עבור קובצי צנצנת ופום:
רעיון IntelliJ: פירוק, קומפילציה, החלפה (או איך לתקן טעויות של אנשים אחרים) - 11
זה נובע מהעובדה שתלות נוספות במצב שינה מצוינות בקובץ ה-pom. ונשאר לנו רק שלב אחד - ציין את המאגר בסקריפט הבנייה שלנו:

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