gradleでjarを出力するに関する自メモ

はじめに

【Android】AndroidStudioでjarを出力する | AdMax Tech Blog

の記事読んでて、なにげに引っかかったの自メモとして修正記載しておく。

古い記事だから仕方ないのかな?

通常のjavaプロジェクトの場合

  • 自前でやる

  • fatjar plugin を使う

多分ココらへんは Gradle徹底入門 辺りで記載されている情報

Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築

Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築

で、これをそのままandroidに当てはめようとしてハマっている人が多い気がする。。

G様の独自pluginのドキュメントレス仕様*1なので、

ここはGradleが悪いって話でもないかなとは正直思いますが*2

android library projectの場合

ここが本題。

  • libP/build/gradle
task clearJar(type: Delete) {
    delete 'build/libs/' + "${出力される.jarの名前}" + '-' + "${バージョン}" + '.jar'
}
task makeJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('release/') //★
    include('classes.jar')
    rename('classes.jar', "${出力される.jarの名前}" + '-' + "${バージョン}" + '.jar')
}
makeJar.dependsOn(clearJar, build)

な記載があるんですが、//★ とかのディレクトリが実際無いので動かない。

エラーも何も出ないんですよね。

まあだから、android gradle plugin ってファイルが消せないとかでも過剰にthrow Exceptionでtask止めようとしていたりしていますが・・

でもまあ、clean時に削除するフォルダがない/消せない ごときでtaskエラーになるのは勘弁してほしいんですけどね・・*3

で修正記載

まずaarとかの出力先は下記ときまっているので、それに揃えるべきかなと思う

  • build/outputs/aar
  • build/outputs/jar

  • libP/build/gradle

import com.android.builder.core.DefaultManifestParser 
android { 
    defaultConfig { 
        def manifestParser = new DefaultManifestParser(android.sourceSets.main.manifest.srcFile) 
        applicationId = manifestParser.getPackage() 
        versionName = manifestParser.getVersionName() 
        versionCode manifestParser.getVersionCode() 
        minSdkVersion manifestParser.getMinSdkVersion() 
        targetSdkVersion manifestParser.getTargetSdkVersion() 
    }
}

であるとした場合、(上記はAndroidManifest.xmlから読み込む例。記載がないなら直定義参照でも問題ない)

def outputJarDir = 'build/outputs/jar'
task clearJar(type: Delete) {
    delete outputJarDir //◎jarを指定するのはナンセンスではない?
}
task makeJar(type: Copy) {
    mkdir outputJarDir
    
    from('build/intermediates/bundles/release/') //★★
    into(outputJarDir) 
    include('classes.jar')
    rename('classes.jar', "${android.defaultConfig.applicationId}-${android.defaultConfig.versionName}.jar")
}
makeJar.dependsOn(clearJar, build)

と記載すべきかなと

あと //★★ だとdebugログは出ないんですけど、外部提供目的なら問題ないのか?? *4

libPフォルダ内でmakeJarタスクを実行させたい場合は

  • gradlew/gradlew.bat/gradleフォルダをプロジェクトのROOT => libPフォルダにコピー
  • apply plugin の上にjcenterの参照を記載
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.+'
    }
}

apply plugin: 'com.android.library'

*1:DSLとか

*2:ASが使うのがしんどいのは元になったIDEAの質が悪いわけではなく、G様の魔改造のせいなだけ

*3:特にWin環境でハマりやすい

*4:個人的には社内利用ならdebugビルドでproguardを後でかければ良い気もするんだけど