JavaRush /وبلاگ جاوا /Random-FA /ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا ن...
Viacheslav
مرحله

ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران)

در گروه منتشر شد
"چرخ را دوباره اختراع نکن" یکی از قوانین اصلی برای کار موفق و کارآمد است. اما وقتی نمی‌خواهید چرخ خود را دوباره اختراع کنید، اما فرمان شخص دیگری کج شده و چرخ‌ها مربع هستند، چه باید کرد؟ این بررسی قصد دارد تا حد ممکن مقدمه ای مختصر در مورد تکنیک تعمیر کتابخانه های افراد دیگر "به عنوان آخرین راه حل" و نحوه گسترش آن به رایانه شما ارائه دهد.
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 1

معرفی

همه ما از یک ابزار یا ابزار دیگر استفاده می کنیم. اما گاهی اوقات ابزارها کاملا مناسب نیستند یا دارای خطا هستند. به لطف ویژگی های زبان جاوا، می توانیم رفتار ابزارها را در جایی که به آن نیاز داریم اصلاح کنیم. وقتی در پروژه‌ها مشارکت می‌کنیم و درخواست‌های کششی ارسال می‌کنیم، خوب است (می‌توانید در اینجا بیشتر بخوانید: « GitHub - مشارکت در پروژه‌ها »). اما ممکن است بلافاصله پذیرفته نشوند یا حتی پذیرفته نشوند. اما برای نیازهای پروژه در حال حاضر ضروری است. و در اینجا، امیدوارم این مقاله ابزارهایی را که در دسترس ما به عنوان توسعه دهندگان است، نشان دهد. ما باید مراحل زیر را انجام دهیم که در مورد آنها صحبت خواهیم کرد:
  • برای مثال یک برنامه آزمایشی آماده کنید (با استفاده از مثال پروژه Hibernate)
  • یافتن مکان قابل تغییر
  • ایجاد تغییر
  • استقرار مخزن
تمام مراحل زیر برای سیستم عامل ویندوز ارائه شده است، اما دارای آنالوگ برای سیستم های nix است. بنابراین در صورت لزوم می توانید آنها را تکرار کنید.

آماده سازی موضوع

بنابراین، ما به یک پروژه آزمایشی نیاز داریم. Hibernate برای ما ایده آل است، زیرا ... این "شیک، مد روز، مدرن" است. من زیاد وارد جزئیات نمی شوم، زیرا ... مقاله درباره Hibernate نیست. ما همه چیز را به سرعت و به درستی انجام خواهیم داد. و ما مانند توسعه دهندگان مناسب از سیستم ساخت استفاده خواهیم کرد. مثلا Gradle هم برای ما مناسب است که باید برای این مقاله ( https://gradle.org/install/ ) نصب شود. ابتدا باید یک پروژه ایجاد کنیم. Maven کهن الگوهایی برای این کار دارد و Gradle یک پلاگین ویژه برای این کار دارد: Gradle Init . بنابراین، خط فرمان را به هر طریقی که برای شما شناخته شده است باز کنید. یک دایرکتوری برای پروژه ایجاد کنید، به آن بروید و دستور را اجرا کنید:

mkdir javarush 
cd javarush 
gradle init --type java-application
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 2
قبل از وارد کردن پروژه، اجازه دهید تغییراتی در فایلی که نحوه ساخت آن را توضیح می دهد، ایجاد کنیم. این فایل build script نام دارد و build.gradle نام دارد. در دایرکتوری قرار دارد که gradle init را در آن اجرا کردیم. بنابراین، ما به سادگی آن را باز می کنیم (مثلاً در ویندوز با دستور 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 را پیکربندی کنیم. Hibernate یک « راهنمای شروع به کار » دارد، اما احمقانه است و بیشتر یک مانع است تا کمک. بنابراین، بیایید مانند افراد مناسب مستقیماً به « راهنمای کاربر » برویم. در فهرست مطالب، بخش " Bootstrap " را می بینیم که به عنوان "Bootstrapping" ترجمه می شود. فقط آنچه شما نیاز دارید. کلمات هوشمند زیادی در آنجا نوشته شده است، اما نکته اینجاست که باید یک دایرکتوری META-INF در مسیر کلاس وجود داشته باشد و یک فایل persistence.xml وجود داشته باشد. طبق استاندارد، classpath حاوی دایرکتوری "منابع" است. بنابراین، دایرکتوری مشخص شده را ایجاد می کنیم: 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. عالی، تنها چیزی که باقی می ماند راه اندازی است. بیایید به فصل بوت استرپ برگردیم . از آنجایی که ما یک سرور کاربردی نداریم که محیط 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 را بگیریم و نقاط شکست را در آنجا قرار دهیم ( BreakPoint ). پس از درج در خط مورد نظر، این کار را می توان با استفاده از Ctrl+F8 یا از طریق منوی Run -> Toggle Line Breakpoint انجام داد. سپس روش اصلی خود را در اشکال زدایی اجرا می کنیم (Run -> Debug):
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 3
مثال کمی دست و پا چلفتی است، اما فرض کنید می خواهیم تعداد فضاهای پرس و جو را در هنگام راه اندازی تغییر دهیم. همانطور که می بینیم، sqlQuery ما NativeQueryImpl است. کلیک کنید Ctrl+N، نام کلاس را بنویسید و به آن بروید. به طوری که وقتی به یک کلاس می رویم، به محلی که این کلاس در آن قرار دارد منتقل می شویم و autoscroll را روشن می کنیم:
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 4
اجازه دهید بلافاصله توجه داشته باشیم که Idea در حال حاضر نمی داند کد منبع برنامه (یعنی کد منبع) را از کجا پیدا کند. بنابراین، او با مهربانی محتویات فایل کلاس را برای ما دیکامپایل کرد:
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 5
همچنین توجه داشته باشید که در عنوان پنجره IntelliJ Idea نوشته شده است که Gradle آرتیفکت را برای ما ذخیره می کند. اکنون، بیایید مسیری را که مصنوع ما در آن قرار دارد، در Idea قرار دهیم:
ایده 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. وای، شما نمی توانید آن را بدون خطا و کامپایل کنید. ما تعداد زیادی خطای Cannot Find Symbol را دریافت کردیم، زیرا... کلاس mutable به کلاس‌های دیگر گره خورده است، که IntelliJ Idea معمولاً برای ما به classpath اضافه می‌کند. آیا همه مفید بودن IDE های ما را احساس می کنید؟ =) خب بیایید خودمان اضافه کنیم، ما هم می توانیم این کار را انجام دهیم. بیایید مسیرهای زیر را کپی کنیم:
  • [1] - hibernate-core-5.2.17.Final.jar
  • [2] - hibernate-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 بازنشانی نمی شوند. بنابراین، اجرای برنامه در جایی که قبلا بود متوقف می شود. Voila، ما می بینیم که تغییرات ما چگونه کار می کنند:
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 9
عالی. اما در اینجا این سؤال مطرح می شود - به دلیل چیست؟ صرفاً به این دلیل است که وقتی gradle یک پروژه را می‌سازد، بلوک‌های وابسته و مخازن را تجزیه و تحلیل می‌کند. Gradle یک build cache خاص دارد که در یک مکان خاص قرار دارد (به « نحوه تنظیم مکان gradle cache؟ » مراجعه کنید اگر هیچ وابستگی در حافظه پنهان وجود نداشته باشد، Gradle آن را از مخزن دانلود خواهد کرد. خود کش، سپس Gradle فکر می کند که کتابخانه در حافظه پنهان است و چیزی را پمپ نمی کند. اما هر گونه پاک کردن حافظه پنهان منجر به از بین رفتن تغییرات ما می شود. چه باید کرد. هوم، دانلود از مخزن؟ پس ما به مخزن خود با ترجیحات و شاعران نیاز داریم. این مرحله بعدی است.

استقرار مخزن

راه حل های رایگان مختلفی برای استقرار مخزن شما وجود دارد: یکی از آنها Artifactory و دیگری Apache Archive است . Artifactory مد روز، شیک، مدرن به نظر می رسد، اما من با آن مشکل داشتم، نمی خواستم مصنوعات را به درستی قرار دهم و ابرداده های Maven اشتباهی ایجاد کردم. بنابراین، به طور غیرمنتظره برای خودم، نسخه آپاچی برای من کار کرد. معلوم شد که چندان زیبا نیست، اما قابل اعتماد کار می کند. در صفحه دانلود ، به دنبال نسخه مستقل بگردید و آن را باز کنید. آنها " شروع سریع " خود را دارند . پس از راه اندازی، باید منتظر بمانید تا آدرس http://127.0.0.1:8080/#repositorylist. پس از آن، "Upload Artifact" را انتخاب کنید:
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 10
روی «شروع آپلود» و سپس «ذخیره فایل‌ها» کلیک کنید. پس از این، یک پیام موفقیت آمیز سبز ظاهر می شود و مصنوع در بخش "مرور" در دسترس قرار می گیرد. این باید برای فایل های jar و pom انجام شود:
ایده IntelliJ: کامپایل کردن، کامپایل کردن، جایگزینی (یا نحوه اصلاح اشتباهات دیگران) - 11
این به دلیل این واقعیت است که وابستگی های اضافی hibernate در فایل pom مشخص شده است. و فقط 1 مرحله باقی مانده است - مخزن را در اسکریپت ساختمان مشخص کنید:

repositories {
    jcenter()
    maven {
        url "http://127.0.0.1:8080/repository/internal/"
    }
}
و بر این اساس، نسخه hibernate ما تبدیل می شود: 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