অতিরিক্ত ক্লাসপাথ বিকল্পের সাথে "জাভা-মাইফাইল.জার" কল করুন


93

আমি আমার সমস্ত সংকলিত জিনিসযুক্ত একটি জার ফাইল তৈরি করেছি। অতিরিক্তভাবে আমার পিঁপড়া বিল্ড স্ক্রিপ্ট একটি প্রয়োজনীয় সাব-ফোল্ডার "libs" এ কপি করে। কাঠামোটি এর মতো দেখাচ্ছে:

MyProgram.jar
libs/

সুতরাং আমি এখন যখন আমার প্রোগ্রামটি চালানোর চেষ্টা করি তখন আমি নিম্নলিখিত ত্রুটিটি পাই:

java -cp ".:/home/user/java/MyProgram/jar/libs" -jar MyProgram.jar
java.lang.ClassNotFoundException: org.postgresql.Driver
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:186)
    at database.PostgresQL.getConnection(PostgresQL.java:38)
    at recommender.dao.Creative2IdxDAO.createCreatives2Idx(Creative2IdxDAO.java:19)
    at main.Main.calculateCorrelationMatrix(Main.java:51)
    at main.Main.main(Main.java:28)
java.lang.NullPointerException
    at recommender.dao.Creative2IdxDAO.createCreatives2Idx(Creative2IdxDAO.java:25)
    at main.Main.calculateCorrelationMatrix(Main.java:51)
    at main.Main.main(Main.java:28)

কেন এমন হয়?

উত্তর:


153

আপনি উভয়ই ব্যবহার করুন -jar বা -cp , আপনি দুটি একত্রিত করতে পারবেন না। আপনি যদি ক্লাসপথে অতিরিক্ত জেআর লাগাতে চান তবে আপনাকে সেগুলি মূল জেআর এর ম্যানিফেস্টে স্থাপন করা উচিত এবং তারপরে java -jarআপনি সম্পূর্ণ ক্লাসপথটি (মূল জেআর এবং এর নির্ভরতা সহ) লিখুন -cpএবং প্রধান শ্রেণীর নাম কমান্ড লাইনে স্পষ্টভাবে লিখুন

java -cp 'MyProgram.jar:libs/*' main.Main

(আমি dir/*সিনট্যাক্সটি ব্যবহার করছি যা javaকমান্ডকে .jarএকটি নির্দিষ্ট ডিরেক্টরি থেকে শ্রেণিপথে সমস্ত ফাইল যুক্ত করার নির্দেশ দেয় Note মনে রাখবেন যে *শেল দ্বারা প্রসারণ থেকে অবশ্যই সুরক্ষিত থাকতে হবে, এজন্য আমি একক উদ্ধৃতি ব্যবহার করেছি।)

আপনি উল্লেখ করেছেন যে আপনি পিঁপড়া ব্যবহার করছেন তাই বিকল্প প্রকাশ্য পদ্ধতির জন্য, আপনি নির্ভরতা অনুলিপি করার পরে কিন্তু জার তৈরির আগে পিঁপড়ার <manifestclasspath>কাজটি ব্যবহার করতে পারেন ।

<manifestclasspath property="myprogram.manifest.classpath" jarfile="MyProgram.jar">
  <classpath>
    <fileset dir="libs" includes="*.jar" />
  </classpath>
</manifestclasspath>

<jar destfile="MyProgram.jar" basedir="classes">
  <manifest>
    <attribute name="Main-Class" value="main.Main" />
    <attribute name="Class-Path" value="${myprogram.manifest.classpath}" />
  </manifest>
</jar>

এটি জায়গায় রয়েছে, java -jar MyProgram.jarসঠিকভাবে কাজ করবে এবং libsক্লাসপাথে সমস্ত জেআর ফাইলও অন্তর্ভুক্ত করবে ।


উপরে যুক্ত করা বা MANIFEST.MF ফাইলে প্রয়োজনীয় জার এন্ট্রি যুক্ত করার কথা ভাবুন।
হিমাংশু ভরদ্বাজ

@ হিমাংশু ভরদ্বাজ প্রকৃতপক্ষে, আমি কীভাবে এটি ব্যবহার করতে পারি তার একটি উদাহরণ যোগ করেছি<manifestclasspath>
ইয়ান রবার্টস

'মাইপ্রগ্রাম.জার: লাইবস / *'-তে ':' কীভাবে বিচ্ছিন্ন?
গোব্লিনস

লিনাক্স এবং ম্যাক অপারেটিং সিস্টেমের আওতায় পাথের আইটেমগুলির মধ্যে বিভক্তকারী হ'ল @ গব্লিন্স কোলন। উইন্ডোজে আপনি সেমিকোলন ( ;) পরিবর্তে উইন্ডোতে কোলন ড্রাইভ অক্ষরের জন্য ব্যবহার করা হবে। ওপি তাদের প্রশ্নে কলোন এবং ফরোয়ার্ড স্ল্যাশ ব্যবহার করেছিল, তারা বোঝায় যে তারা লিনাক্স বা ম্যাকে রয়েছে।
ইয়ান রবার্টস

4
বিকল্পগুলি যদি পারস্পরিকভাবে একচেটিয়া হয় তবে কমান্ড লাইনটি দুটি ব্যবহার করার সময় একটি সতর্কতা মুদ্রণ করা উচিত। এই ট্রিভিয়ার জন্য সময় কে আছে ?!
জেজেএস

23

যখন -jarবিকল্প ব্যবহার করা হয় -cpবিকল্প উপেক্ষা করা হয়। ক্লাসপাথ সেট করার একমাত্র উপায় হ'ল জারে ম্যানিফেস্ট ফাইল ব্যবহার করা।

কেবল -cpঅপশনটি ব্যবহার করা সহজ , আপনার জার ফাইলটি এতে যুক্ত করুন, তারপরে স্পষ্টভাবে প্রধান শ্রেণিকে কল করুন।

এছাড়াও, ধরে নিই যে /home/user/java/MyProgram/jar/libsফোল্ডারে জার ফাইল রয়েছে (শ্রেণি ফাইলগুলির বিপরীতে) এটি কাজ করবে না। আপনি জার ফাইলের একটি ফোল্ডার নির্দিষ্ট করতে পারবেন না তবে প্রতিটি জার ফাইল পৃথক পৃথকভাবে শ্রেণিপথে নির্দিষ্ট করতে হবে (উল্লেখযোগ্য সংখ্যক জার থাকলে আপনার জন্য এটি করার জন্য একটি সাধারণ শেল স্ক্রিপ্ট লেখার পক্ষে মূল্যবান)।


0

এটা কিছুটা কৃপণ। নীচের স্ক্রিপ্টটি জারটির ম্যানিফেস্ট থেকে ক্লাসপাথ পাওয়ার চেষ্টা এবং তারপরে অতিরিক্ত ক্লাসপাথ এন্ট্রি যুক্ত করার অনুমতি দেওয়া। আমি এর সাথে মিশ্রিত ফলাফল পেয়েছি তবে তবুও স্ক্রিপ্টটি ভাগ করতে চাই তাই এটি এখানে পুরোপুরি কার্যকর হতে পারে।

স্ক্রিপ্টের দুটি নাম রয়েছে

  • প্রদর্শনী
  • কলজার

একসাথে দুটি ফাইলকে হার্ডলিঙ্ক করে

ln calljar showmanifest

কলজারের সাথে আপনি ব্যবহার দেখতে পারেন।

#!/bin/bash
#set -x
# show the manifest of a jar file
# 2012-07-18
# author WF

#
# show usage
#
usage() {
 echo "usage: showmanifest (jarfile | directory jarfile) " 1>&2
 echo "usage: calljar directory jarfile classpath pattern arguments" 1>&2
 echo "             -h|--help " 1>&2
 echo "               show this help and exit" 1>&2
 echo "             -m|--mainclass javaclass" 1>&2
 echo "               mainclass to use (otherwise manifest is inspected)" 1>&2
 exit 1
}

#
# show the manifest of the given jar file
#
show() {
  dir="$1"
  jar="$2"
    fulljar=`find "$dir" -name "$jar"`
    cd /tmp
    mkdir show$$
    cd show$$
    jar xvf $fulljar META-INF/MANIFEST.MF
    cat META-INF/MANIFEST.MF
    cd /tmp
    rm -rf show$$
}

#
# show the classpath of the manifest
#
calljar() {
  dir="$1"
    jar="$2"
    classpath="$3"
    pattern="$4"
    arguments="$5"
    cmd=`show "$dir" "$jar"   | awk -v extracp="$classpath" -v dir="$dir" -v pattern="$pattern" -v jar="$jar" -v mainclass="$mainclass" -v args="$arguments" '
/Main-Class: / { if (mainclass=="") mainclass=$2 }
/^Class-Path:/ { 
  incp=1; 
    cp=$0; 
    gsub("Class-Path: ","",cp) 
    next
}
/^ .*$/ && incp { 
    line=substr($0,2)
  # remove carriage return (if any)
  cp=cp line
}
END { 
  # we do not like carriage returns
  gsub("\\r","",cp)
  gsub("\\r","",mainclass)
    # we do not like blanks ...
  gsub(" ","",cp)
    gsub(pattern,":"dir"/"pattern,cp)
  print "java -cp " extracp cp ":"dir"/"jar " " mainclass " " args
}
    '`
  #echo $cmd
    $cmd
}


# echo $# arguments found: $*
# parse command line options
while true; do
# echo "option $1"
  case "$1" in
    # options without arguments
    -h|--help) usage;;
         # for options with required arguments, an additional shift is required
        -m|--mainclass) mainclass=$2; shift;;
      (--) shift; break;;
      (-*) echo "$0: error - unrecognized option $1" 1>&2; usage;;
    (*) dir=$1;shift;break;;
  esac
  shift
done

#echo "argcount=$#"
case  $# in
  0) dir=`dirname "$dir"`
       jar=`basename "$dir"`
         show "$dir" "$jar";;
  1) jar="$1"
         show "$dir" "$jar";;
  2) usage;;
    3) usage;;
  *) jar="$1"; shift;
         classpath="$1"; shift;
         pattern="$1"; shift;
         arguments="$@";
    #echo "mainclass=${mainclass}"
    #echo "classpath=${classpath}"

  #echo calljar "${dir}" "${jar}" "${classpath}" "$pattern" "$arguments"
    calljar "$dir" "$jar" "$classpath" "$pattern" "$arguments"
    ;;
esac

-1

কোনও অ্যাপ্লিকেশনটির দ্রুত, এক-অফ পরীক্ষার জন্য, আপনি কেবল প্রয়োজনীয় অ্যাপ্লিকেশন জেআর ফাইলগুলি মূল অ্যাপ্লিকেশন জেআর ফাইল যুক্ত ডিরেক্টরিতে সিমলিংক করতে পারেন।

উদাহরণ (একটি অ্যাপ্লিকেশন app.jarযা গ্রহগ্রহ এসডাব্লুটি লাইব্রেরি ব্যবহার করে, যা আমার ক্ষেত্রে ইনস্টল করা হয়েছিল /usr/share/java):

$ ln -s /usr/share/java/swt.jar .
$ java -jar app.jar
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.