كيف أقوم بتضمين الجرار في برنامج نصي رائع؟[ينسخ]

StackOverflow https://stackoverflow.com/questions/306139

  •  08-07-2019
  •  | 
  •  

سؤال

لدي نص رائع يحتاج إلى مكتبة في جرة.كيف يمكنني إضافة ذلك إلى مسار الفصل؟أريد أن يكون البرنامج النصي قابلاً للتنفيذ لذلك أستخدمه #!/usr/bin/env groovy في الجزء العلوي من البرنامج النصي الخاص بي.

هل كانت مفيدة؟

المحلول

إذا كان عليك فعل ذلك، يمكنك أيضًا تحميل JAR في وقت التشغيل باستخدام:

this.getClass().classLoader.rootLoader.addURL(new File("file.jar").toURL())

نصائح أخرى

بدء البرنامج النصي رائع مع #!/usr/bin/env groovy لديه قيود مهمة جدا - لا يمكن إضافة أي وسائط إضافية. لا يمكن تكوين مسار فئة، ولا يمكن تشغيل رائع مع تعريفات أو تصحيح الأخطاء.هذه ليست رائع مشكلة، ولكن وجود قيود على كيفية Shebang (#!) يعمل - يتم التعامل مع جميع الوسائط الإضافية كوسيطة واحدة #!/usr/bin/env groovy -d يقول /usr/bin/env لتشغيل الأمر groovy -d ثم بعد ذلك groovy مع حجة d.

هناك حل بديل لهذه المشكلة، والذي يتضمن تشغيل رائع باستخدام bash في السيناريو رائع.

#!/bin/bash                                                                                                                                                                 
//usr/bin/env groovy  -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" $@; exit $?

import org.springframework.class.from.jar
//other groovy code
println 'Hello'

كل السحر يحدث في أول سطرين.يخبرنا السطر الأول أن هذا هو bash النصي. bash يبدأ تشغيل ويرى السطر الأول.في bash # هو للتعليقات و // انهار ل / وهو الدليل الجذر.لذا bash سيتم تشغيل /usr/bin/env groovy -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" $@ والذي يبدأ رائعًا بكل الحجج التي نريدها.ال "$0" هو الطريق إلى البرنامج النصي لدينا، و $@ هي الحجج.الآن يتم تشغيل رائع ويتجاهل السطرين الأولين ويرى النص الرائع الخاص بنا ثم يخرج مرة أخرى إلى bash. bash ثم يخرج (exit $?1) مع رمز الحالة من رائع.

يمكنك إضافة الجرار إلى $HOME/.groovy/lib

طريقتي المفضلة للقيام بذلك هي باستخدام Groovy Grapes.يصل هؤلاء إلى مستودع Maven المركزي، ويقومون بتنزيل الجرة المشار إليها، ثم يضعونها في مسار الفصل.وبعد ذلك يمكنك استخدام المكتبة كأي مكتبة أخرى.بناء الجملة بسيط حقا:

@Grab(group='com.google.collections', module='google-collections', version='1.0')

يمكنك قراءة المزيد من التفاصيل هنا.إحدى المزايا الرئيسية هنا هي أنك لا تحتاج إلى توزيع تبعياتك عند توزيع البرنامج النصي الخاص بك.العيب الوحيد لهذه الطريقة هو أن الجرة يجب أن تكون في مستودع Maven.

يمكنك أيضًا تجربة Groovy Grape.يتيح لك استخدام التعليقات التوضيحية لتعديل مسار الفصل.إنها تجريبية الآن، ولكنها رائعة جدًا.يرى docs.groovy-lang.org/.../grape

نفس ما تفعله في جافا.

هذا مثال على تشغيل البرنامج النصي لمراقبة حالة MySQL.يحتوي mysql.jar على موصل MySQL الذي أستدعيه من البرنامج النصي Status.groovy.

رائع -cp mysql.jar Status.groovy ct1

وفيما يلي مزيج من الحل باتريك, حل مارتن بوكهولد, وتعليق foozbar الذي يعمل مع كل من Linux وCygwin:

#!/bin/bash
// 2>/dev/null; SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
// 2>/dev/null; OPTS="-cp $SCRIPT_DIR/lib/extra.jar:$SCRIPT_DIR/lib/spring.jar"
// 2>/dev/null; OPTS="$OPTS -d"
// 2>/dev/null; OPTS="$OPTS -Dlog4j.configuration=file:/etc/myapp/log4j.xml"
// 2>/dev/null; exec groovy $OPTS "$0" "$@"; exit $?

import org.springframework.class.from.jar
//other groovy code
println 'Hello'

كيف تعمل:

  • // هو تعليق رائع صالح، لذا يتجاهل Groovy كافة أوامر bash.
  • // سيرجع خطأ، ولكن تتم إعادة توجيه إخراج الخطأ إلى /dev/null وبالتالي لا يتم عرضها.
  • ينفذ bash الأوامر بعد الفاصلة المنقوطة على الرغم من فشل الأمر السابق.
  • exec يستبدل البرنامج الحالي في العملية الحالية دون التفرع عن عملية جديدة.وبالتالي، يتم تشغيل رائع ضمن عملية البرنامج النصي الأصلي (ps يُظهر العملية كبرنامج نصي بدلاً من الملف القابل للتنفيذ الرائع)
  • ال exit $? البيان التالي exec groovy يمنع bash من محاولة تفسير بقية البرنامج النصي على أنه برنامج نصي bash، ويحافظ أيضًا على رمز الإرجاع من البرنامج النصي الرائع.

تعد خدعة bash المذكورة أعلاه أكثر ملاءمة في بعض الحالات من خدعة RootLoader لأنه يمكنك استخدام عبارات الاستيراد العادية داخل البرنامج النصي.يفرض عليك استخدام خدعة RootLoader تحميل كافة الفئات باستخدام الانعكاس.يعد هذا أمرًا جيدًا في بعض المواقف (مثل عندما تحتاج إلى تحميل برنامج تشغيل JDBC)، ولكنه غير مناسب في حالات أخرى.

إذا كنت تعلم أن البرنامج النصي الخاص بك لن يتم تنفيذه أبدًا على Cygwin، فمن المرجح أن يؤدي استخدام حل Patrick أو Maarteen إلى أداء أفضل قليلًا لأنهما يتجنبان العبء الزائد الناتج عن إنشاء الخطأ والتخلص منه.

إضافة إلى @Patrick إجابته، التي ساعدتني كثيرًا، اكتشفت مؤخرًا خدعة أخرى.

إذا قمت بإضافة الكثير من الجرار إلى مسار الفصل الدراسي في سطر واحد، فقد تصبح الأشياء غير قابلة للقراءة تمامًا.ولكن يمكنك القيام بما يلي!

#!/bin/bash
//bin/true && OPTS="-cp blah.jar -Dmyopt=value"
//bin/true && OPTS="$OPTS -Dmoreopts=value2"
//usr/bin/env groovy $OPTS "$0" $@; exit $?

println "inside my groovy script"

أطلق العنان لمخيلتك حول مدى تعقيد سطر الأوامر الذي يمكنك تقسيمه بهذه الطريقة إلى أجزاء يمكن التحكم فيها

مارتن

إذا كنت تريد استخدامه على الفور قبل import تصريحات ممكن هكذا :) :

// printEmployees.groovy
this.class.classLoader.rootLoader.addURL(
   new URL("file:///C:/app/Dustin/product/11.1.0/db_1/jdbc/lib/ojdbc6.jar"))
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:orcl", "hr", "hr",
                      "oracle.jdbc.pool.OracleDataSource")
sql.eachRow("SELECT employee_id, last_name, first_name FROM employees")
{
   println "The employee's name is ${it.first_name} ${it.last_name}."
}

مأخوذ من هذا مقالة javaworld.com.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top