تجميع JAR مع التبعيات في Maven: دليل خطوة بخطوة للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

«تطبيقك يعمل فقط في IDE؟ حان الوقت لإصلاح ذلك!»

\n\n

إذا سبق لك أن كتبت بلغة Java، فمن المحتمل أنك واجهت هذا الموقف: تظهر بفخر مشروعك الجديد لصديق، وتشغله في IntelliJ IDEA أو Eclipse - كل شيء يعمل بشكل مثالي. ولكن بمجرد أن تسلم هذا المشروع لزميل أو تحاول تشغيله عبر سطر الأوامر، تستقبلك رسالة ClassNotFoundException أو NoClassDefFoundError. هل هذا مألوف؟

\n\n

في معظم الدورات التعليمية والبرامج التعليمية، يوضحون كيفية إنشاء ملف JAR باستخدام Maven، لكنهم غالبًا ما يغفلون تفصيلًا مهمًا: أين تذهب التبعيات؟. ملف JAR العادي يحتوي فقط على الكود الخاص بك، بينما تبقى جميع المكتبات (مثل Apache Commons، Jackson، JUnit) خارجة. ولهذا السبب يظهر السؤال الذي يطرحه ملايين مطوري Java على Stack Overflow: «How can I create an executable/runnable JAR with dependencies using Maven?»

\n\n

في هذه المقالة، سنستعرض عدة طرق مجربة لتجميع JAR قابل للتنفيذ مع التبعيات باستخدام Maven. ستتعلم كيفية إعداد maven-assembly-plugin و maven-shade-plugin وحتى كيفية عمل ذلك في Spring Boot. هيا بنا!

\n\n

لماذا لا يعمل JAR العادي؟

\n\n

لنقم بتجربة بسيطة. تخيل أن لديك تطبيقًا يقوم بتحليل JSON باستخدام مكتبة Jackson. تقوم بإنشاء JAR عادي بأمر mvn package، ثم تحاول تشغيله:

\n\n
java -jar my-app.jar
\n\n

وستحصل على شيء مثل:

\n\n
Exception in thread "main" java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ObjectMapper
\n\n

لماذا يحدث هذا؟ لأن Maven بشكل افتراضي يقوم بتغليف الكود المترجم الخاص بك فقط (الفئات من مجلد src/main/java). جميع التبعيات التي حددتها في pom.xml تبقى في المستودع المحلي لـ Maven (~/.m2/repository). عند تشغيل JAR، لا تعرف JVM أين تبحث عن هذه المكتبات، فتصدر خطأ.

\n\n

الحل هو إنشاء fat JAR (JAR سميك) أو uber JAR، والذي يحتوي بداخله ليس فقط على فئاتك ولكن أيضًا على جميع التبعيات الضرورية. ولهذا الغرض توجد إضافات Maven خاصة.

\n\n

الطريقة 1: maven-assembly-plugin (بسيط وموثوق)

\n\n

الطريقة الأكثر شيوعًا وبساطة هي استخدام maven-assembly-plugin. يقوم بإنشاء JAR حيث يتم فك ضغط جميع التبعيات ودمجها مع فئاتك. دعنا نضبطه.

\n\n

أضف الكود التالي إلى pom.xml الخاص بك في قسم <build><plugins>:

\n\n
<plugin>\n    <groupId>org.apache.maven.plugins</groupId>\n    <artifactId>maven-assembly-plugin</artifactId>\n    <version>3.6.0</version>\n    <configuration>\n        <descriptorRefs>\n            <descriptorRef>jar-with-dependencies</descriptorRef>\n        </descriptorRefs>\n        <archive>\n            <manifest>\n                <mainClass>com.example.Main</mainClass>\n            </manifest>\n        </archive>\n    </configuration>\n    <executions>\n        <execution>\n            <id>make-assembly</id>\n            <phase>package</phase>\n            <goals>\n                <goal>single</goal>\n            </goals>\n        </execution>\n    </executions>\n</plugin>
\n\n

هام: استبدل com.example.Main بالاسم الكامل لفئتك التي تحتوي على طريقة main.

\n\n

الآن قم ببناء المشروع بالأمر:

\n\n
mvn clean package
\n\n

في مجلد target سيظهر ملفان:

\n
    \n
  • my-app.jar - عادي

المدونات

توصيات الكتب