ग्रेडेल के साथ रन करने योग्य जार बनाना


148

अब तक मैंने एक्लिप्स "एक्सपोर्ट ..." फंक्शनैलिटी के माध्यम से रन करने योग्य JAR फाइल्स बनाई लेकिन अब मैं बिल्ड ऑटोमेशन के लिए IntelliJ IDEA और ग्रैडल में बदल गया।

यहां कुछ लेख "एप्लिकेशन" प्लगइन का सुझाव देते हैं, लेकिन यह पूरी तरह से मेरे द्वारा अपेक्षित परिणाम नहीं देता है (बस एक JAR, कोई शुरुआत स्क्रिप्ट या ऐसा कुछ भी नहीं)।

मैं एक ही परिणाम कैसे प्राप्त कर सकता हूं ग्रहण "निर्यात ..." संवाद के साथ करता है?

जवाबों:


164

एक निष्पादन योग्य जार फ़ाइल केवल एक जार फ़ाइल है जिसमें इसके प्रकट होने में मुख्य-वर्ग प्रविष्टि है। तो आपको केवल इस कार्य को इसके प्रकट में जोड़ने के लिए जार कार्य को कॉन्फ़िगर करने की आवश्यकता है :

jar {
    manifest {
        attributes 'Main-Class': 'com.foo.bar.MainClass'
    }
}

आपको मैनिफ़ेस्ट में क्लासपैथ प्रविष्टियाँ जोड़ने की भी आवश्यकता हो सकती है, लेकिन यह उसी तरह किया जाएगा।

Http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html देखें


6
ऐसा लगता है कि मैं क्या देख रहा था; लेकिन: मैंने बिल्ड.ग्रेड में पहले से ही निर्भरता की घोषणा की है, क्या मुझे वास्तव में मैन्युअल रूप से वर्ग पथ को जोड़ना होगा या क्या मैं अपनी निर्भरता घोषणा का फिर से उपयोग कर सकता हूं?
हेंस

आपको 'रनटाइम' कॉन्फ़िगरेशन के अंदर पुस्तकालयों के माध्यम से लूप करने में सक्षम होना चाहिए और क्लास-पाथ एट्रीब्यूशन वैल्यू बनाने के लिए उन्हें संक्षिप्त करना चाहिए।
जेबी निज़ेट

3
"रनटाइम" कॉन्फ़िगरेशन के बारे में जानकारी देने के साथ आपका क्या मतलब है? बेवकूफ सवालों के लिए क्षमा करें, मैं ग्रैडल के लिए काफी नया हूं ...
हेंस

ग्रैवल जावा प्लगइन 4 अलग-अलग क्लासपैथ के अनुरूप 4 "कॉन्फ़िगरेशन" को परिभाषित करता है: संकलन (जावा फ़ाइलों को संकलित करने के लिए उपयोग किया जाता है), testCompile (जो परीक्षण जावा स्रोत फ़ाइलों को संकलित करने के लिए उपयोग किया जाता है), रनटाइम (जो एप्लिकेशन को निष्पादित करने के लिए उपयोग किया जाता है) और testRuntime (जिसका उपयोग परीक्षणों को निष्पादित करने के लिए किया जाता है)। देखें gradle.org/docs/current/userguide/...
जेबी Nizet

आह, धन्यवाद - मैंने इसे सही समझा और JAR के निर्माण का प्रबंधन किया, अब मैं क्लासपैथ बनाने के लिए तैयार हूं;; आपकी मदद के लिए बहुत बहुत धन्यवाद!
हेंस

98

JB Nizet और Jorge_B दोनों के उत्तर सही हैं।

अपने सरलतम रूप में, ग्रैडल के साथ एक निष्पादन योग्य JAR बनाना केवल प्रकट में उपयुक्त प्रविष्टियों को जोड़ने की बात है । हालाँकि, यह निर्भरता के लिए बहुत अधिक सामान्य है जिसे क्लासपाथ में शामिल करने की आवश्यकता है, जिससे यह दृष्टिकोण व्यवहार में मुश्किल हो जाता है।

आवेदन प्लगइन एक वैकल्पिक दृष्टिकोण प्रदान करता है; एक निष्पादन योग्य JAR बनाने के बजाय, यह प्रदान करता है:

  • एक runकाम को आसानी से निर्माण से सीधे आवेदन चल रहा है की सुविधा के लिए
  • एक ऐसा installDistकार्य जो निर्मित JAR, जिसमें यह निर्भर करता है, के सभी सहित एक निर्देशिका संरचना उत्पन्न करता है, और एक स्टार्टअप स्क्रिप्ट जो एक कार्यक्रम में सभी को एक साथ खींचती है जिसे आप चला सकते हैं
  • distZipऔर ऐसे distTarकार्य जो पूर्ण अनुप्रयोग वितरण (स्टार्टअप स्क्रिप्ट और JAR) युक्त अभिलेखागार बनाते हैं

एक तीसरा दृष्टिकोण एक तथाकथित "मोटा जार" बनाना है जो एक निष्पादन योग्य जार है जिसमें न केवल आपके घटक का कोड शामिल है, बल्कि इसके सभी निर्भरताएं भी शामिल हैं। कुछ अलग प्लगइन्स हैं जो इस दृष्टिकोण का उपयोग करते हैं। मैंने कुछ ऐसे लिंक शामिल किए हैं जिनसे मैं परिचित हूं; मुझे पूरा भरोसा है कि वहां और अधिक चीजे हैं।


बस छाया और एक-जार की कोशिश की। मैं वन-जार से चिपका रहूँगा: यह सरल और उपयोग में आसान है। ठंडा! धन्यवाद
Jako

दुर्भाग्य से एक-जार ग्रेड के हाल के संस्करणों के साथ काम नहीं करता है। उदाहरण के लिए देखें, github.com/rholder/gradle-one-jar/issues/34
pharsicle

जार कार्य को संशोधित करके वन-जार बनाने के लिए यहां एक-लाइनर समाधान है। मैंने इसे सबसे सुविधाजनक पाया है। ध्यान दें कि आपको configurations.runtimeएकल जार में रनटाइम निर्भरता को जोड़ने की आवश्यकता है ।
क़ाज़ी इरफ़ान

मुझे अपनी आवश्यकता के लिए उपयुक्त और लचीला होने के लिए "एप्लिकेशन प्लगइन" मिला। यह सब कुछ ज़िप करने के लिए पैक करने और उस ज़िप में अतिरिक्त फ़ाइलों को शामिल करने / बाहर करने की अनुमति देता है। इसके अलावा, कस्टम कार्य का उपयोग करके अतिरिक्त प्रविष्टि बिंदु के साथ एक और लॉन्चर स्क्रिप्ट जोड़ना संभव है।
कीनोरनिरवाना २

मैं उत्पन्न .tar/ .zipफ़ाइलों को कैसे निष्पादित करूंगा ?
तोबिक

35

जैसा कि अन्य ने नोट किया है, जार फ़ाइल को निष्पादन योग्य बनाने के लिए, एप्लिकेशन की प्रविष्टि बिंदु को प्रदर्शन Main-Classफ़ाइल की विशेषता में सेट किया जाना चाहिए । यदि निर्भरता वर्ग की फाइलें ढह नहीं रही हैं, तो उन्हें Class-Pathमैनिफ़ेस्ट फ़ाइल की प्रविष्टि में सेट करने की आवश्यकता है ।

मैंने सभी प्रकार के प्लगइन संयोजनों की कोशिश की है और निष्पादन योग्य जार बनाने के सरल कार्य के लिए क्या और किसी तरह किसी और पर निर्भरता शामिल है। सभी प्लगइन्स में एक या दूसरे तरीके की कमी लगती है, लेकिन अंत में मुझे यह पसंद आया जैसे मैं चाहता था। कोई रहस्यमय स्क्रिप्ट, बिल्ड डाइरेक्टरी को प्रदूषित करने वाली एक लाख अलग-अलग मिनी फाइल्स नहीं, एक बहुत ही साफ बिल्ड स्क्रिप्ट फाइल, और सबसे ऊपर: एक मिलियन विदेशी थर्ड पार्टी क्लास फाइल्स मेरे जार आर्काइव में विलय नहीं हुईं।

आपकी सुविधा के लिए यहाँ से कॉपी-पेस्ट निम्नलिखित है ..

[कैसे करें] उपनिर्देशिका में निर्भरता जार के साथ एक वितरण ज़िप फ़ाइल बनाएँ /libऔर सभी निर्भरताएँ Class-Pathप्रकट फ़ाइल में प्रवेश करने के लिए जोड़ें :

apply plugin: 'java'
apply plugin: 'java-library-distribution'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.2'
}

// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)

jar {
    // Keep jar clean:
    exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'

    manifest {
        attributes 'Main-Class': 'com.somepackage.MainClass',
                   'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
    }
    // How-to add class path:
    //     /programming/22659463/add-classpath-in-manifest-using-gradle
    //     https://gist.github.com/simon04/6865179
}

यहां एक जिस्ट के रूप में होस्ट किया गया ।

परिणाम में पाया जा सकता है build/distributionsऔर अनजिप की गई सामग्री इस तरह दिखती है:

lib / commons-lang3-3.3.2.jar
MyJarFile.jar

की सामग्री MyJarFile.jar#META-INF/MANIFEST.mf:

घोषणापत्र-संस्करण: 1.0
मुख्य-वर्ग: com.somepackage.MainClass
क्लास-पाथ: लिब / कॉमन्स- lang3-3.3.2.jar


वर्तमान एप्लिकेशन जार वितरण के 'लिबास' निर्देशिका में भी होगा। आपको या तो इसे शीर्ष निर्देशिका में ले जाना होगा या इस रेखा को बदलना होगा: 'क्लास-पाथ': configurations.runtime.files.collect {"lib / $ it.name"} .join ('' ')} इसको: 'क्लास-पाथ': कॉन्फिगरेशन ।runtime.files.collect {"$ it.name"} .join ('' ')}
मार्क नूरी

1
@MarcNuri क्या आपको यकीन है? मैं अपने आवेदन के लिए इस दृष्टिकोण का उपयोग करने की कोशिश की है, और वर्तमान आवेदन जार था नहीं में libउत्पादित ज़िप / टार फ़ाइल की निर्देशिका, बल्कि में था libकी मूल निर्देशिका, के रूप में इस जवाब पता चलता है। यह समाधान मेरे लिए पूरी तरह से काम कर रहा था।
thejonwithnoh

1
@thejonwithnoh मुझे क्षमा करें, आप सही हैं। मैंने "जावा-लाइब्रेरी-डिस्ट्रीब्यूशन" प्लगइन का उपयोग करने के लिए प्रस्तावित समाधान नहीं देखा। मेरे मामले में मैं बस "एप्लिकेशन" प्लगइन का उपयोग कर रहा हूं जो मुख्य अंतर के साथ एक ही काम करता है कि सभी जार फाइलें ( एप्लिकेशन जार सहित ) "काम" निर्देशिका में स्थित हैं। इस प्रकार काम "lib/$it.name"करने के लिए बदल रहा है "$it.name"
मार्क नूरी

28

मेरे लिए कम-से-कम प्रयास समाधान को ढाल-छाया-प्लगइन का उपयोग करना था

प्लगइन को लागू करने के अलावा, जो करने की आवश्यकता है वह है:

अपने मुख्य वर्ग को प्रकट करने के लिए जार कार्य को कॉन्फ़िगर करें

jar {
  manifest {
   attributes 'Main-Class': 'com.my.app.Main'
  }
}

धाविका कार्य चलाएँ

./gradlew shadowJar

लो एप्लिकेशन संस्करण-all.jar से निर्माण / libs /

और अंत में इसके माध्यम से निष्पादित करें:

java -jar app-version-all.jar


जब मैं इसका निर्माण करता हूं तो मुझे BUILD SUCCESSFUL मिलता है लेकिन जब मैं java फाइल को java -jar build / libs / core-all-1.0.jar से चलाने की कोशिश करता हूं तो मुझे निम्नलिखित त्रुटि मिलती है: त्रुटि: मुख्य वर्ग स्कैनर .exchange को ढूंढ या लोड नहीं कर सका। मुख्य कारण: java.lang.ClassNotFoundException: स्कैनर्स.एक्सचेंज.मुझे क्या आप जानते हैं कि मैं इसे कैसे हल कर सकता हूं?
लुका लोपुसीना

@LukaLopusina आपके द्वारा निर्दिष्ट वर्ग आपकी JAR फ़ाइल में नहीं है। यदि आप कोटलिन का उपयोग कर रहे हैं, तो आपको कहना होगा 'com.my.app.MainKt'। अधिक जानकारी के बिना, मैं आपकी आगे मदद नहीं कर सकता।
byxor

वर्तमान प्लगइन शैडो v5। + ग्रैडल 5.0+ और जावा 7+ के साथ ही संगत है।
ज़ोन

5

क्या आपने 'installApp' कार्य करने की कोशिश की है? क्या यह शुरुआत स्क्रिप्ट के सेट के साथ एक पूर्ण निर्देशिका नहीं बनाता है?

http://www.gradle.org/docs/current/userguide/application_plugin.html


मैं जो समझता हूं, installAppवह META-INF/MANIFEST.MFफ़ाइल नहीं बनाता है । क्या मुझसे कुछ गलत हो रही है?
अद्वैत

1
मुझे एप्लिकेशन प्लगिनinstallApp की कार्य सूची में कार्य दिखाई नहीं देता है । क्या आपको इसके बजाय मतलब था? installDist
क़ाज़ी इरफ़ान

2
हां, ग्रैडल 3.0 में installAppइसका नाम बदल दिया गया installDist। यहाँ जारी नोट है
क़ाज़ी इरफ़ान

4

आपको कॉन्स्टेंटिन धन्यवाद, यह कुछ बारीकियों के साथ एक आकर्षण की तरह काम करता था। किसी कारण से, मुख्य वर्ग को जार मेनिफ़ेस्ट के हिस्से के रूप में निर्दिष्ट करने से बहुत काम नहीं हुआ और वह इसके बजाय mainClassName विशेषता चाहता था। यहाँ build.gradle से एक स्निपेट है जिसमें इसे काम करने के लिए सब कुछ शामिल है:

plugins {
  id 'java' 
  id 'com.github.johnrengelman.shadow' version '1.2.2'
}
...
...
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
...
...
mainClassName = 'com.acme.myapp.MyClassMain'
...
...
...
shadowJar {
    baseName = 'myapp'
}

ढाल छाया चलाने के बाद, आपको अपने बिल्ड फ़ोल्डर में myapp- {version} -all.jar मिलता है जिसे जावा -जर मायप्प- {version} -all.jar के रूप में चलाया जा सकता है।


3

आप मॉड्यूल सेटिंग्स (या प्रोजेक्ट संरचना) में एक जार विरूपण साक्ष्य को परिभाषित कर सकते हैं।

  • मॉड्यूल क्लिक करें> निर्भर मॉड्यूल के साथ मॉड्यूल से ओपन मॉड्यूल सेटिंग्स> कलाकृतियों> +> जार>।
  • मुख्य वर्ग निर्धारित करें।

जार बनाना तब बिल्ड मेनू से "बिल्ड आर्टवर्क ..." पर क्लिक करना जितना आसान होता है। एक बोनस के रूप में, आप सभी निर्भरताओं को एक जार में पैकेज कर सकते हैं।

इंटेलीज आईडीईए 14 परम पर परीक्षण किया गया।


2

मैंने समाधान के लिए कुछ लिंक की जाँच की, अंत में नीचे दिए गए चरणों को काम करने के लिए बताया। मैं ग्रैडल 2.9 का उपयोग कर रहा हूं।

अपनी बिल्ड, ग्रेडल फ़ाइल में निम्नलिखित बदलाव करें:

  1. उल्लेख प्लगइन:

    apply plugin: 'eu.appsatori.fatjar'
  2. बिल्डस्क्रिप्ट प्रदान करें:

    buildscript {
    repositories {
        jcenter()
    }
    
    dependencies {
        classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
    }
    }
  3. मुख्य वर्ग प्रदान करें:

    fatJar {
      classifier 'fat'
      manifest {
        attributes 'Main-Class': 'my.project.core.MyMainClass'
      }
      exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
    }
  4. फतवा बनाएँ:

    ./gradlew clean fatjar
  5. फतवा चलाओ / निर्माण करो / काम करो /:

    java -jar MyFatJar.jar

1
2019 से: यह सुझाव यहां काम नहीं करता है। कोई निर्भरता fatjar में शामिल हैं
कार्ल

1

आप स्प्रिंगबूट प्लगइन का उपयोग कर सकते हैं:

plugins {
  id "org.springframework.boot" version "2.2.2.RELEASE"
}

जार बनाएँ

gradle assemble

और फिर इसे चलाएं

java -jar build/libs/*.jar

नोट: इस प्लगइन का उपयोग करने के लिए आपके प्रोजेक्ट को स्प्रिंगबूट प्रोजेक्ट होने की आवश्यकता नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.