JavaRush /مدونة جافا /Random-AR /فكرة IntelliJ: التفكيك، التجميع، الاستبدال (أو كيفية تصحي...
Viacheslav
مستوى

فكرة IntelliJ: التفكيك، التجميع، الاستبدال (أو كيفية تصحيح أخطاء الآخرين)

نشرت في المجموعة
"لا تعيد اختراع العجلة" هي إحدى القواعد الأساسية للعمل الناجح والفعال. ولكن ماذا تفعل عندما لا ترغب في إعادة اختراع العجلة الخاصة بك، ولكن عجلة القيادة لشخص آخر تبين أنها ملتوية والعجلات مربعة؟ تهدف هذه المراجعة إلى تقديم مقدمة مختصرة قدر الإمكان عن تقنية إصلاح مكتبات الأشخاص الآخرين "كملجأ أخير" وكيفية توسيع نطاق ذلك ليشمل جهاز الكمبيوتر الخاص بك.
فكرة IntelliJ: التفكيك أو التجميع أو الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 1

مقدمة

نحن جميعا نستخدم أداة واحدة أو أخرى. لكن في بعض الأحيان لا تكون الأدوات مناسبة تمامًا أو تحتوي على أخطاء. بفضل ميزات لغة Java، يمكننا تصحيح سلوك الأدوات حيثما نحتاج إليها. من الجيد أن نساهم في المشاريع ونرسل طلبات السحب (يمكنك قراءة المزيد هنا: " GitHub - المساهمة في المشاريع "). لكن قد لا يتم قبولهم على الفور، أو قد لا يتم قبولهم حتى. ولكن لاحتياجات المشروع فمن الضروري الآن. وهنا، آمل أن توضح هذه المقالة الأدوات المتاحة لنا كمطورين. سنحتاج إلى تنفيذ الخطوات التالية التي سنتحدث عنها:
  • قم بإعداد تطبيق اختباري على سبيل المثال (باستخدام مثال مشروع السبات)
  • العثور على موقع للتغيير
  • إجراء تغيير
  • نشر المستودع
جميع الخطوات المذكورة أدناه معطاة لنظام التشغيل Windows، ولكن لها نظائرها لأنظمة 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). نجد كتلة " التبعيات " هناك، أي. التبعيات. جميع الجرار الخارجية التي سنستخدمها موصوفة هنا. الآن نحن بحاجة إلى فهم ما يجب وصفه هنا. دعنا نذهب إلى موقع السبات ( 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 على " دليل البدء "، ولكنه غبي ويعد عائقًا أكثر من كونه مساعدة. لذلك، دعنا ننتقل مباشرة إلى " دليل المستخدم " مثل الأشخاص المناسبين. في جدول المحتويات، نرى القسم " Bootstrap "، والذي يُترجم إلى "Bootstrapping". فقط ما تحتاجه. هناك الكثير من الكلمات الذكية المكتوبة هناك، ولكن النقطة المهمة هي أنه يجب أن يكون هناك دليل META-INF على مسار الفصل، ويجب أن يكون هناك ملف Persistence.xml. وفقًا للمعيار، يحتوي مسار الفصل على دليل "الموارد". لذلك، نقوم بإنشاء الدليل المحدد: mkdir src\main\resources\META-INF قم بإنشاء ملف الثبات.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. التطبيق الذي تم تشغيله 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. ثم نقوم بتشغيل طريقتنا الرئيسية في التصحيح (تشغيل -> تصحيح):
فكرة IntelliJ: التفكيك أو التجميع أو الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 3
هذا مثال أخرق بعض الشيء، ولكن لنفترض أننا نريد تغيير عدد مساحات الاستعلام عند بدء التشغيل. كما نرى، فإن sqlQuery الخاص بنا هو NativeQueryImpl. انقر فوق Ctrl+Nواكتب اسم الفصل وانتقل إليه. بحيث عندما نذهب إلى فصل دراسي، سيتم نقلنا إلى المكان الذي يوجد به هذا الفصل وتشغيل التمرير التلقائي:
فكرة IntelliJ: التفكيك أو التجميع أو الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 4
دعونا نلاحظ على الفور أن Idea لا تعرف حاليًا مكان العثور على الكود المصدري للبرنامج (أي الكود المصدري). لذلك، تفضلت بتفكيك محتويات ملف الفصل الدراسي لنا:
فكرة IntelliJ: التفكيك أو التجميع أو الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 5
لاحظ أيضًا أنه في عنوان نافذة IntelliJ Idea مكتوب حيث يحفظ Gradle القطعة الأثرية لنا. الآن، دعنا ندخل في Idea إلى المسار الذي توجد به القطعة الأثرية لدينا:
فكرة IntelliJ: التفكيك أو التجميع أو الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 6
دعنا نذهب إلى هذا الدليل في سطر الأوامر باستخدام الأمر cd way to каталогу. سأقدم ملاحظة على الفور: إذا كان من الممكن بناء مشروع من المصدر، فمن الأفضل أن نبني من المصدر. على سبيل المثال، كود مصدر السبات متاح على الموقع الرسمي. من الأفضل استلامه للإصدار المطلوب وإجراء جميع التغييرات هناك وتجميعه باستخدام نصوص الإنشاء المحددة في المشروع. أقدم في المقالة الخيار الأكثر فظاعة - هناك جرة، ولكن لا يوجد كود المصدر. والملاحظة رقم 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] - السبات النواة 5.2.17.Final.jar
  • [2] - السبات-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. يمكن أن نسترشد بالمواد الرسمية : jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class على الأرجح لن تسمح لك Open IntelliJ Idea بتغيير الملفات. لذلك، قبل إجراء تحديث الجرة، سيتعين عليك على الأرجح إغلاق Idea، وبعد التحديث، افتحه. بعد ذلك، يمكنك إعادة فتح IDE وتشغيل dubug مرة أخرى. لا تتم إعادة تعيين نقاط التوقف بين عمليات إعادة تشغيل IDE. ولذلك، فإن تنفيذ البرنامج سوف يتوقف حيث كان من قبل. Voila، نحن نرى كيف تعمل تغييراتنا:
فكرة IntelliJ: التفكيك، التجميع، الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 9
عظيم. ولكن هنا يطرح السؤال - لماذا؟ ببساطة يرجع ذلك إلى حقيقة أنه عندما يقوم Gradle ببناء مشروع، فإنه يقوم بتحليل كتلة التبعيات والمستودعات. يحتوي Gradle على ذاكرة تخزين مؤقت معينة للإنشاء، والتي توجد في موقع معين (راجع " كيفية تعيين موقع ذاكرة التخزين المؤقت لـ gradle؟ " إذا لم تكن هناك تبعية في ذاكرة التخزين المؤقت، فسيقوم Gradle بتنزيلها من المستودع. نظرًا لأننا قمنا بتغيير الجرة في "ذاكرة التخزين المؤقت نفسها، ثم يعتقد Gradle أن المكتبة موجودة في ذاكرة التخزين المؤقت ولا تضخ أي شيء. ولكن أي مسح لذاكرة التخزين المؤقت سيؤدي إلى فقدان تغييراتنا. بالإضافة إلى ذلك، لا يمكن لأحد غيرنا الذهاب والحصول عليها. كم من الإزعاج ، أليس كذلك؟ ما يجب القيام به. حسنًا، التنزيلات من المستودع؟ لذلك نحن بحاجة إلى مستودعنا، مع التفضيلات والشاعرات. هذه هي الخطوة التالية.

نشر المستودع

هناك حلول مجانية مختلفة لنشر مستودعك: أحدهما Artifactory والآخر هو Apache Archive . يبدو Artifactory عصريًا وأنيقًا وحديثًا، لكنني واجهت صعوبات في ذلك، ولم أرغب في وضع القطع الأثرية بشكل صحيح وأنشأت بيانات وصفية خاطئة. لذلك، بشكل غير متوقع بالنسبة لي، عملت نسخة أباتشي بالنسبة لي. اتضح أنها ليست جميلة جدًا، لكنها تعمل بشكل موثوق. في صفحة التنزيل ، ابحث عن الإصدار المستقل وقم بفك ضغطه. لديهم " البداية السريعة " الخاصة بهم. بعد الإطلاق، عليك الانتظار حتى العنوان http://127.0.0.1:8080/#repositorylist. بعد ذلك، حدد "تحميل القطعة الأثرية":
فكرة IntelliJ: التفكيك أو التجميع أو الاستبدال (أو كيفية تصحيح أخطاء الآخرين) - 10
انقر على "بدء التحميل"، ثم "حفظ الملفات". بعد ذلك، ستظهر رسالة نجاح خضراء وستصبح القطعة الأثرية متاحة في قسم "التصفح". يجب أن يتم ذلك بالنسبة لملفات jar و pom:
فكرة 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