I've a library project in Android studio that will be used in both Android and Java projects. I'm publishing this library to my own remote artifact repository in both .aar and .jar formats using the maven-publish plugin that's shipped with Android Studio. I can fetch and use the library properly in an Android app however when I try to use it in a Java project, intellij and eclipse are unable to detect even if the library is there even though gradle/maven is fetching the library from the remote repo. I've tried pushing only aar to the remote repo and fetching that in Java projects but that didn't workout either. Please note that I've no Android dependency/resources in this library. Following is the script being used to generate and push the artifacts to remote server.
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
android.libraryVariants.all { variant ->
variant.outputs.all {
outputFileName = "${_groupId}-${_artifactId}-${android.defaultConfig.versionName}.aar"
}
}
task sourceJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier "sources"
}
task deleteOldJar(type:Delete){
delete 'release/MyLibrary.jar'
}
task exportJar(type:Copy){
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
rename('classes.jar','MyLibrary.jar')
}
publishing {
repositories {
maven {
url _remoteRepoUrl
}
}
publications {
library(MavenPublication) {
groupId _groupId
artifactId _artifactId
version android.defaultConfig.versionName
artifact(sourceJar)
artifact(exportJar)
artifact ("$buildDir/outputs/aar/${_groupId}-${_artifactId}-${android.defaultConfig.versionName}.aar") { //aar artifact you want to publish
builtBy assembleDebug
}
//generate pom nodes for dependencies
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dependency ->
println "dependency name is: "+dependency.name
if(!dependency.name.equals('unspecified')) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
dependencyNode.appendNode('type', "aar")
}
else
println "dependency name is unspecified"
}
}
}
}
}
What am I doing wrong?
I found the solution. Turns out the com.android.library plugin in gradle was somehow messing with the generated artifact such that only Android projects could use the library artifact and not the plain java projects. Since my library doesn't have any layout resources, I can skip making .aar and just generate a jar file. For generating the jar file and publishing it to the remote repo following snippet is being utilized:
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'maven-publish'
sourceCompatibility = 1.8
def _remoteRepoUrl = "http://myserver.com/repo"
def _groupId = group
def _versionName = version
repositories {
mavenCentral()
jcenter()
maven {
url _remoteRepoUrl
}
flatDir {
dirs 'libs'
}
}
jar {
from sourceSets.main.output
}
task jarWithSources(type: Jar) {
from sourceSets.main.output
if (gradle.startParameter.taskNames.any{it == "publishToMavenLocal"}) {
from sourceSets.main.allJava
}
}
// Define how maven-publish publishes to the nexus repository
publishing {
repositories {
maven {
url _remoteRepoUrl
}
}
publications {
mavenJava(MavenPublication) {
from components.java
}
// publish the <project> jar as a standalone artifact
mavenJar(MavenPublication) {
artifact jarWithSources
//from components.java -- can't have both the above line and this
//artifactId "${jar.baseName}_jar"
version project.version
}
}
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'
}
}
Related
Once Gradle has downloaded the dependencies I'm trying to iterate over each jar file, extract a specific file, swagger yml, into a folder. However, when I execute the task it returns NO-SOURCE.
The task to extract the file into a folder:
task unzip(type: Copy) {
configurations.artifact.asFileTree.each {
from zipTree(it).matching { include "OpenApi-*.yml" }
into 'swaggerExtract/'
}
}
build.gradle
repositories {
mavenLocal()
}
configurations {
artifact
}
dependencies {
artifact 'com.example.android:accounts-service:0.0.2-SNAPSHOT'
artifact 'com.example.android:my-service:0.0.4.RELEASE'
}
apply plugin: 'java'
I'm having a lot of trouble figuring out how to compile a GRPC Java server. I looked all over the grpc.io website and closest thing I found was this: http://www.grpc.io/docs/#quick-start , where I run
../gradlew -PskipCodegen=true installDist to build, and
./build/install/grpc-examples/bin/hello-world-client to run the client. This all works, but only for the hello-world tutorial. I have no idea how to do this for my own client/server. I'm able to generate the client/server protobufs using the .proto file. I looked in their readme and Java tutorial and couldn't find out how to compile the actual server (and client) after I write them
https://github.com/grpc/grpc-java/blob/master/examples/README.md
(can't link java tutorial because I dont have enough reputation). Unless there's documentation im missing, does anyone know how to compile a server and client that implements the GRPC classes generated from the .proto file? I did spend a fair amount of time searching. Any advice is much appreciated, thanks.
Also have a similar problem, ensure that:
You configured correctly the protoc, that will be downloading the executable and configure it as an environment variable of your OS.
The build.gradle file, make sure to include protobuf-gradle-plugin:
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'com.google.protobuf'
ext.grpcVersion = '1.0.1'
ext.protobufVersion = '3.0.2'
buildscript {
repositories { mavenCentral() }
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' }
}
repositories {
mavenCentral()
}
dependencies {
compile "com.google.protobuf:protobuf-java:${protobufVersion}"
compile "io.grpc:grpc-all:${grpcVersion}"
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protobufVersion}" }
plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } }
generateProtoTasks { ofSourceSet('main')*.plugins { grpc { } } }
}
idea {
module {
sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java");
sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/grpc");
}
}
Your proto file:
syntax = "proto3";
package com.company.project;
service CompanyService{
rpc call(RequestMessage) returns (ResponseMessage) {}
}
Run gradle clean build, and it should generate your service and client classes for CompanyService.
The idea plugin, is jut for telling IntelliJ to recognize the src/main/proto as a source set.
To actually execute the client and server, you will need to make the implementation, mentioned in the tutorial for gRpc, and then apply the application plugin, in order to generate correctly the executable jar
//build.grdle code...
apply plugin: 'application'
mainClassName = 'com.company.project.MainClass'
jar { manifest { attributes('Main-Class' : mainClassName) } }
I had a similar issue but solved it using it in Gradle by adding the 'application' plugin. Before I was using the 'java' plugin and I could only generated a jar file. After switching to the 'application' plugin there is a gradle task similar to the gRPC example.
./gradlew installDist
And now to start your server you can run something similar to this:
./build/install/your-project/bin/your-server
To actually generate the Java classes off my .proto files I needed to run './gradle build' and also include the source generated using the sourceDir element you can see in the build.gradle below.
This is the full build.gradle file.
apply plugin: 'application'
apply plugin: 'com.google.protobuf'
apply plugin: 'idea'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.6'
}
}
repositories {
jcenter()
}
dependencies {
compile 'io.grpc:grpc-all:0.14.0'
}
mainClassName = "com.domain.service.YourMainClass"
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.0.0-beta-2"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:0.14.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
idea {
module {
sourceDirs += file("${projectDir}/build/generated/source/proto/main/grpc");
sourceDirs += file("${projectDir}/build/generated/source/proto/main/java");
}
}
I am new to gRPC so any improvments to my Gradle file would be appericated.
This question has been answered on groups.google.com by 'Eric Anderson':
The JAR only has your code in it. It sounds like you want to make a "fat" jar which includes all your dependencies. You can do something like this:
jar {
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
Note that that isn't gRPC-specific; it's just working with Gradle. There may be alternatives, such as a quick Googling returned gradle-fatjar-plugin.
I have the following directory structure:
myapp/
src/main/resources/
<lots of code>
build.gradle
With the following build.gradle:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'eclipse'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
group = 'net.myuser'
repositories {
jcenter()
}
dependencies {
compile(
<dependencies here>
)
}
jar {
baseName = 'myapp'
}
task writePom << {
pom {
project {
groupId group
artifactId 'myapp'
version version
inceptionYear '2015'
licenses {
license {
name 'myapp'
distribution 'Blah blah blah'
}
}
}
}.writeTo("build/libs/pom.xml")
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
artifacts {
archives(file("${buildDir}/libs/myapp-${version}.jar")) {
name "myapp"
classifier ""
}
}
When I do:
./gradlew clean build writePom install -Pversion=0.1.0
I get two problems:
Inside the generated build/libs/pom.xml the groupId is showing as null; and
I cannot find a net.myuser directory under ~/.gradle/caches/modules-2, which tells me install is not working
So I ask: What do I need to change so that groupId isn't null, and how do I get install publishing all of the following:
JAR
Sources JAR
Javadoc JAR
pom.xml
As per comment, use groupId project.group instead of groupId group in order to set the <groupId> properly.
Regarding the install task, please have a look at Gradle Maven Plugin documentation:
Installs the associated artifacts to the local Maven cache, including Maven metadata generation.
By default, the local Maven cache is located in ~/.m2/repository, thus you are looking at the wrong location. The install task does not tamper with ~/.gradle/caches/modules-2 which is (as the name already implies) only a cache for resolved dependencies.
By using the Maven plugin, Gradle already creates a POM file for you. So please check if you really need a custom writePom task.
Also, the main artifact is installed automatically, so this might be redundant:
artifacts {
archives(file("${buildDir}/libs/myapp-${version}.jar")) {
name "myapp"
classifier ""
}
}
I'm trying to get my gradle script to upload to an sftp account, but it keeps failing with error,
Failed to deploy artifacts: Could not transfer artifact com.himself12794:Heroes-Mod:jar:0.9-rev1 from/to remote (sftp://himself1#ftp.himself12794-develops.com:18765/public_html/maven): Could not write to resource 'com/himself12794/Heroes-Mod/0.9-rev1/Heroes-Mod-0.9-rev1.jar'
I'm able to connect via sftp command:
sftp -P 18765 himself1#ftp.himself12794-develops.com
However, the publishMavenJavaPublicationToMavenRepository task fails, with the above error.
This is a Minecraft Forge mod, if that sheds any light on things.
My build.gradle is like so:
buildscript {
repositories {
jcenter()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.0- SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: "maven-publish"
// for people who want stable
/*plugins {
id "net.minecraftforge.gradle.forge" version "2.0.1"
id "maven-publish"
}*/
repositories {
maven {
name = "himself12794-develops"
url = "http://maven.himself12794-develops.com"
}
}
version = "0.9-rev1"
group = "com.himself12794"
archivesBaseName = "Heroes-Mod"
minecraft {
version = "1.8-11.14.3.1514"
runDir = "run"
mappings = "snapshot_20141130"
// makeObfSourceJar = false
}
dependencies {
compile "com.himself12794:powersAPI:1.1-rev2"
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
publishing {
repositories {
maven {
url "sftp://himself1#ftp.himself12794-develops.com:18765"
}
}
}
processResources
{
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
expand 'version':project.version, 'mcversion':project.minecraft.version
}
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
Any assistance anyone can give is greatly appreciated.
I have not solved this specific problem yet, but I have discovered that the problem with the original maven plugin that caused me to try the maven-publish plugin was actually an issue with the current stable version of Gradle (2.7). Using the current nightly wrapper build has allowed me to circumvent this.
I successfully uploaded my jars to a nexus repository using the maven plugin for gradle but it didn't upload the sources. This is my configuration:
uploadArchives {
repositories{
mavenDeployer {
repository(url: "http://...") {
authentication(userName: "user", password: "myPassword")
}
}
}
}
I searched and found that I can add the sources by adding a new task.
task sourcesJar(type: Jar, dependsOn:classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives sourcesJar
}
This works fine but I think there must be a better solution by configuring the maven plugin, something like uploadSource = true like this:
uploadArchives {
repositories{
mavenDeployer {
repository(url: "http://...") {
authentication(userName: "user", password: "myPassword")
}
uploadSources = true
}
}
}
There is no better solution than what you described yourself. The gradle maven plugin is uploading all artifacts generated in the current project. That's why you have to explicitly create a "sources" artifact.
The situation also doesn't change when using the new maven-publish plugin. Here, you also need to explicitly define additional artifacts:
task sourceJar(type: Jar) {
from sourceSets.main.allJava
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar {
classifier "sources"
}
}
}
}
The reason is that gradle is more about being a general build tool and not bound to pure Java projects.
You can use gradle-nexus-plugin
In order to use the plugin, add the lines below and import plugin
buildscript {
repositories {
mavenLocal()
jcenter {
url "http://jcenter.bintray.com/"
}
}
dependencies {
classpath 'com.bmuschko:gradle-nexus-plugin:2.3'
}
}
apply plugin: 'com.bmuschko.nexus'
Add this section, where you will configure url to deploy
nexus {
sign = false
repositoryUrl = 'http://localhost:8081/nexus/content/repositories/releases/'
snapshotRepositoryUrl = 'http://localhost:8081/nexus/content/repositories/internal-snapshots/'
}
Note: You must have in ~/.gradle/gradle.properties
nexusUsername = deployment
nexusPassword = deployment123
Nexus for save artifact, not source code.
for upload compiled artifact I do:
apply plugin: 'java'
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://nexus-server:8081/nexus/content/repositories/snapshots") {
authentication(userName: "admin", password: "secret")
}
pom.version = "1.0.0-SNAPSHOT"
pom.artifactId = "${project.name}"
pom.groupId = "path.to.artifact"
}
}
}
and call upload from console
$ gradle upload
for source code use maven or git repository