নির্ভরতা সহ একটি জার তৈরি করতে গ্রেডল ব্যবহার করা


122

আমার একটি মাল্টিপ্রজেক্ট বিল্ড রয়েছে এবং আমি একটি সাবপ্রজেক্টগুলিতে ফ্যাট জার তৈরি করার জন্য একটি টাস্ক রেখেছি। আমি রান্নাঘরের বর্ণিতটির মতোই কাজটি তৈরি করেছিলাম ।

jar {
  from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  manifest { attributes 'Main-Class': 'com.benmccann.gradle.test.WebServer' }
}

এটি চালানো নিম্নলিখিত ত্রুটির ফলাফল:

কারণ: আপনি এমন কনফিগারেশন পরিবর্তন করতে পারবেন না যা অমীমাংসিত অবস্থায় নেই!

আমি নিশ্চিত না যে এই ত্রুটিটির অর্থ কী। এটি কোনও বাগ হওয়ার ক্ষেত্রে গ্র্যাডল JIRA এও জানিয়েছি

উত্তর:


195

আপডেট: নতুন গ্রেডল সংস্করণগুলিতে (4+) compileকোয়ালিফায়ারটি নতুন apiএবং implementationকনফিগারেশনের পক্ষে অবনতিযুক্ত । আপনি যদি এটি ব্যবহার করেন তবে নিম্নলিখিতগুলি আপনার পক্ষে কাজ করা উচিত:

// Include dependent libraries in archive.
mainClassName = "com.company.application.Main"

jar {
  manifest { 
    attributes "Main-Class": "$mainClassName"
  }  

  from {
    configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

পুরানো গ্রেড সংস্করণগুলির জন্য, বা যদি আপনি এখনও আপনার নির্ভরতার জন্য "সংকলন" যোগ্যতা ব্যবহার করেন তবে এটি কাজ করা উচিত:

// Include dependent libraries in archive.
mainClassName = "com.company.application.Main"

jar {
  manifest { 
    attributes "Main-Class": "$mainClassName"
  }  

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

নোট যা mainClassNameঅবশ্যই আগে উপস্থিত হওয়া উচিত jar {


4
আমার প্রজেক্টের জন্য আমাকে কনফিগারেশন.আরুনটাইম কোডের সংশোধন করতে হয়েছিল কারণ আমারও রানটাইম নির্ভরতা রয়েছে।
vextorspace

2
def mainClassNameকোডটি কাজ করতে আমাকে যুক্ত করতে হয়েছিল ... আমি পেয়েছিলাম রুট প্রকল্পের জন্য অজানা সম্পত্তি 'মেইনক্লাসনেম' সেট করতে পারেনি
হ্যানস্কফ

1
আপনি ফাইল নামের সংঘর্ষগুলি কীভাবে পরিচালনা করবেন? বিভিন্ন জারগুলিতে একই পথে ফাইলগুলি ওভাররাইট করা হবে।
wst

3
দুর্ভাগ্যক্রমে এটি আর কাজ করে না। আমি গ্রেড 4.10 এবং implementationএখন হ্রাসের পরিবর্তে নতুন কনফিগারেশন ব্যবহার করি compile। উপরের কোডটি নির্ভরতা ছাড়াই আমাকে একটি ছোট জার তৈরি করে। আমি যখন এটি পরিবর্তন করি ( from { configurations.implementation.collect {...} }), ত্রুটি দেখা দেয় যে কনফিগারেশন 'বাস্তবায়ন' সরাসরি সমাধান করার অনুমতি নেই
বাস্তিয়ান ভয়েগট

1
@ বাস্টিয়ানভয়েগ্ট সমস্তগুলি configurations.compileClasspathঠিক করে দেবে implementation, তবে apiনির্ভরতাগুলি ছেড়ে দেবে। সমাধানের অন্য উত্তরে এখানে পাওয়া গেল runtimeClasspath। এর মধ্যে apiনির্ভরতাও অন্তর্ভুক্ত রয়েছে ।
rekire

64

@ ফেলিক্সের উত্তর আমাকে প্রায় সেখানে নিয়ে এসেছিল। আমার দুটি সমস্যা ছিল:

  1. গ্রেডেল 1.5 এর সাথে, ম্যানিফেস্ট ট্যাগটি ফ্যাটজার টাস্কের মধ্যে স্বীকৃত হয়নি, তাই মূল-শ্রেণীর বৈশিষ্ট্যটি সরাসরি সেট করা যায়নি
  2. জারের মধ্যে বহিরাগত মেটা-আইএনএফ ফাইলগুলি ছিল বিরোধী।

নিম্নলিখিত সেটআপটি এর সমাধান করে

jar {
  manifest {
    attributes(
      'Main-Class': 'my.project.main',
    )
  }
}

task fatJar(type: Jar) {
  manifest.from jar.manifest
  classifier = 'all'
  from {
    configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
  } {
    exclude "META-INF/*.SF"
    exclude "META-INF/*.DSA"
    exclude "META-INF/*.RSA"
  }
  with jar
}

এটিকে স্ট্যান্ডার্ড এসেম্বল বা বিল্ড টাস্কে যুক্ত করতে, যুক্ত করুন:

artifacts {
    archives fatJar
}

সম্পাদনা: @ এমজাগার্ডকে ধন্যবাদ: গ্রেডলের সাম্প্রতিক সংস্করণগুলিতে, এতে পরিবর্তন configurations.runtimeকরুনconfigurations.runtimeClasspath


3
এটি আমার একটি সমস্যাও স্থির করে যেখানে আমার নির্ভরতা জারে একটিতে স্বাক্ষর করা হয়েছিল। স্বাক্ষর ফাইলগুলি আমার জারের META-INF এ রাখা হয়েছিল, কিন্তু স্বাক্ষরটির সাথে আর সামগ্রীর সাথে মেলে না।
ফ্ল্যাভিন

2
এর জন্য বিশেষ ধন্যবাদ artifacts: ঠিক আমি যা খুঁজছিলাম।
অ্যালেক্সার

আপনি যখন gradle fatJarরানটাইম নির্ভরতাগুলি চালনা করেন তা সংকলিত বলে মনে হয় না, তাই সেগুলি অনুলিপি করা যায় না।
mjaggard

64

আপনি যদি jarকাজটি স্বাভাবিকভাবে আচরণ করতে চান এবং অতিরিক্ত কাজও fatJarকরতে চান তবে নিম্নলিখিতটি ব্যবহার করুন:

task fatJar(type: Jar) {
    classifier = 'all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

গুরুত্বপূর্ণ অংশটি হ'ল with jar। এটি ছাড়া এই প্রকল্পের ক্লাসগুলি অন্তর্ভুক্ত নয়।


1
আপনি যদি স্বাক্ষরযুক্ত জারগুলি ব্যবহার করে স্বাক্ষর নিয়ে কোনও সমস্যার জন্য ব্যবহার করেন তবে নীচের সমস্যাটিও দেখুন: স্ট্যাকওভারফ্লো
পিটার এন স্টেইনমেটজ

6
এটা কাজ করে না. এই সমাধান সহ ম্যানিফেস্ট ফাইলটি খালি।
জোনাস

4
আমার 2 সেন্ট: নাম পরিবর্তন করার চেয়ে একটি শ্রেণিবদ্ধ সেট করা ভাল। বেসনাম = প্রজেক্ট.নাম + '-সিল' এর পরিবর্তে শ্রেণিবদ্ধকারী = 'সমস্ত' রাখুন। এইভাবে আপনি মাভেন / নেক্সাস নীতিগুলির সাথে সম্মতি রেখে শিল্পকর্মের নাম রাখবেন।
টাকিয়াসড

1
যোগ করুন group "build"এবং এই টাস্কটি buildগ্রুপে থাকবে (অন্যান্য jarটাস্কের সাথে, যেমন টাস্ক
এমএজিএক্স 2

1
আমি with jarকীওয়ার্ডে কোনও ধরণের ডকুমেন্টেশন খুঁজে পাই না, এটি ঠিক কী করে?
ফিলিপ হেমেলমায়ার

9

এটি আমার পক্ষে ভাল কাজ করে।

আমার প্রধান শ্রেণি:

package com.curso.online.gradle;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

public class Main {

    public static void main(String[] args) {
        Logger logger = Logger.getLogger(Main.class);
        logger.debug("Starting demo");

        String s = "Some Value";

        if (!StringUtils.isEmpty(s)) {
            System.out.println("Welcome ");
        }

        logger.debug("End of demo");
    }

}

এবং এটি আমার ফাইল build.gradle এর বিষয়বস্তু:

apply plugin: 'java'

apply plugin: 'eclipse'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
    compile  'org.apache.commons:commons-lang3:3.0'
    compile  'log4j:log4j:1.2.16'
}

task fatJar(type: Jar) {
    manifest {
        attributes 'Main-Class': 'com.curso.online.gradle.Main'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

এবং আমি আমার কনসোলে নিম্নলিখিত লিখেছি:

java -jar ProyectoEclipseTest-all.jar

এবং আউটপুট দুর্দান্ত:

log4j:WARN No appenders could be found for logger (com.curso.online.gradle.Main)
.
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more in
fo.
Welcome

6

একটি প্রধান নির্বাহযোগ্য শ্রেণীর সাথে একটি চর্বিযুক্ত জেআর তৈরি করতে, স্বাক্ষরিত জেআরগুলির সাথে সমস্যাগুলি এড়ানো, আমি গ্রেড-ওয়ান-জার প্লাগইন প্রস্তাব করিওয়ান-জেআর প্রকল্পটি ব্যবহার করে এমন একটি সাধারণ প্লাগইন ।

ব্যবহার করা সহজ:

apply plugin: 'gradle-one-jar'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.github.rholder:gradle-one-jar:1.0.4'
    }
}

task myjar(type: OneJar) {
    mainClass = 'com.benmccann.gradle.test.WebServer'
}


5

@ বেনের উত্তর প্রায়শই আমার জন্য কাজ করে কেবলমাত্র আমার নির্ভরতা খুব বেশি এবং আমি নিম্নলিখিত ত্রুটিটি পেয়েছি

Execution failed for task ':jar'.
> archive contains more than 65535 entries.

  To build this archive, please enable the zip64 extension.

এই সমস্যাটি সমাধান করতে আমাকে নীচের কোডটি ব্যবহার করতে হবে

mainClassName = "com.company.application.Main"

jar {
  manifest { 
    attributes "Main-Class": "$mainClassName"
  }  
  zip64 = true
  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

1

যাদের প্রকল্প থেকে একাধিক জার তৈরি করা দরকার For

গ্রেডে একটি ফাংশন তৈরি করুন:

void jarFactory(Jar jarTask, jarName, mainClass) {
    jarTask.doFirst {
        println 'Build jar ' + jarTask.name + + ' started'
    }

    jarTask.manifest {
        attributes(
                'Main-Class':  mainClass
        )
    }
    jarTask.classifier = 'all'
    jarTask.baseName = jarName
    jarTask.from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    {
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }
    jarTask.with jar 
    jarTask.doFirst {
        println 'Build jar ' + jarTask.name + ' ended'
    }
}

তারপরে কল করুন:

task makeMyJar(type: Jar) {
    jarFactory(it, 'MyJar', 'org.company.MainClass')
}

গ্রেড 5 এ কাজ করে।

জার স্থাপন করা হবে ./build/libs


0

আমি shadowJarপ্লাগইন দ্বারা টাস্ক ব্যবহার. com.github.jengelman.gradle.plugins:shadow:5.2.0

ব্যবহারের কেবল চালানো ./gradlew app::shadowJar ফলাফলের ফাইলটি হবেMyProject/app/build/libs/shadow.jar

শীর্ষ স্তরের build.gradleফাইল:

 apply plugin: 'kotlin'

buildscript {
    ext.kotlin_version = '1.3.61'

    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
    }
}

অ্যাপ্লিকেশন মডিউল স্তর build.gradleফাইল

apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'

sourceCompatibility = 1.8

kapt {
    generateStubs = true
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation "org.seleniumhq.selenium:selenium-java:4.0.0-alpha-4"
    shadow "org.seleniumhq.selenium:selenium-java:4.0.0-alpha-4"

    implementation project(":module_remote")
    shadow project(":module_remote")
}

jar {
    exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'
    manifest {
        attributes(
                'Main-Class': 'com.github.kolyall.TheApplication',
                'Class-Path': configurations.compile.files.collect { "lib/$it.name" }.join(' ')
        )
    }
}

shadowJar {
    baseName = 'shadow'
    classifier = ''
    archiveVersion = ''
    mainClassName = 'com.github.kolyall.TheApplication'

    mergeServiceFiles()
}


0

গ্রেডেল 6.3, জাভা গ্রন্থাগার। "জার টাস্ক" থেকে কোডটি " গ্রেড বিল্ড " টাস্ক চালানোর সময় "বিল্ড / লিবস / এক্সওয়াইজ.জার" এর সাথে নির্ভরতা যুক্ত করে ।

plugins {
    id 'java-library'
}

jar {
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

-1

আপনি যদি পিপড়া ব্যবহার করে থাকেন তবে গ্র্যাডলের সাথেও আপনি একই চেষ্টা করতে পারেন:

task bundlemyjava{
    ant.jar(destfile: "build/cookmyjar.jar"){
        fileset(dir:"path to your source", includes:'**/*.class,*.class', excludes:'if any')
        } 
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.