I'm trying to create a custom gradle plugin (100% java) which will automatically configure Artifactory, avoiding the need of the following DSL:
artifactory {
contextUrl = "${artifactory_contextUrl}" //The base Artifactory URL if not overridden by the publisher/resolver
publish {
repository {
contextUrl = "${artifactory_contextUrl}"
repoKey = 'android-dev'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
resolve {
repository {
contextUrl = "${artifactory_contextUrl}"
repoKey = 'android-dev-distributions'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
I'm trying to re-create #agrosner own solution (from https://stackoverflow.com/a/25669431/1880280) but I'm missing "ArtifactoryAction". I can't find it anywhere.
The nonworking version posted by #agrosner is the following code:
// Set up plugins so we never need to add them to a build.gradle
project.getPlugins().apply(MAVEN);
project.getPlugins().apply(ARTIFACTORY);
project.setGroup(GROUP);
// Add Artifactory repo to the repositories
project.getRepositories().maven(new ArtifactoryAction(contextUrl + ARTIFACTORY_REPO_ENDPOINT, user, pass));
// We will define the plugin convention here so all of our libraries do not need to
// declare the artifactory closure manually
ArtifactoryPluginConvention pluginConvention =
ArtifactoryPluginUtil.getArtifactoryConvention(project);
pluginConvention.setContextUrl(contextUrl);
PublisherConfig publisherConfig = new PublisherConfig(pluginConvention);
publisherConfig.setContextUrl(contextUrl);
pluginConvention.setPublisherConfig(publisherConfig);
// Use reflection to access private field
PublisherConfig.Repository repository = null;
Field[] fields = PublisherConfig.class.getDeclaredFields();
for(Field field : fields) {
if(field.getName().equalsIgnoreCase("repository")) {
try {
field.setAccessible(true);
repository = (PublisherConfig.Repository) field.get(publisherConfig);
} catch (Exception e) {
e.printStackTrace();
}
}
}
if(repository != null) {
repository.setPassword(pass);
repository.setUsername(user);
repository.setRepoKey(PUBLISHER_REPO_KEY);
repository.setMavenCompatible(true);
}
GradleArtifactoryClientConfigUpdater.update(pluginConvention.getClientConfig(), project.getRootProject());
Can anyone help with an updated 100% java version of this?
Additionally, how would be for the following DSL?
artifactory {
publish {
repository {
repoKey = 'default-gradle-dev-local' // The Artifactory repository key to publish to
username = "${artifactory_user}" // The publisher user name
password = "${artifactory_password}" // The publisher password
maven = true
}
defaults {
publications('mavenJava')
publishArtifacts = true
publishPom = true
}
}}
Thanks in advance
César
ps. The DSL version that was published at #agrosner question thread is not useful for me. I need a Java version.
For your first question related to ArtifactoryAction: this is neither Gradle API nor Artifactory plugin related api, but most probably a custom class that the response author has implemented himself, as a shortcut to declare his custom Artifactory maven repo.
See this API, used to declare maven repositories :
MavenArtifactRepository maven(Action<? super MavenArtifactRepository> action)
So you can use:
project.getRepositories().maven( mavenArtifactRepository -> {
mavenArtifactRepository.setUrl(contextUrl + MAVEN_PUBLIC_REPO);
mavenArtifactRepository.getCredentials().setUsername("user");
mavenArtifactRepository.getCredentials().setPassword("password");
});
or wrap the action code into a custom implementation of Action<? super MavenArtifactRepository> :
project.getRepositories().maven( new ArtifactoryAction(contextUrl + MAVEN_PUBLIC_REPO, "user", "password") );
[...]
// custom action class, defined somewhere else
class ArtifactoryAction implements Action<MavenArtifactRepository> {
private final String url, userName, password;
ArtifactoryAction(String url, String userName, String password) {
this.url = url; this.userName = userName; this.password = password;
}
#Override
public void execute(MavenArtifactRepository target) {
target.setUrl(url);
target.getCredentials().setUsername(userName);
target.getCredentials().setPassword(password);
}
}
For the other question with java translation of the artifactory { } DSL : see full example below with some inline comments. ( not tested but translated from my kotlin implementation which works fine)
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
import org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin;
import org.jfrog.gradle.plugin.artifactory.ArtifactoryPluginUtil;
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention;
import org.jfrog.gradle.plugin.artifactory.dsl.PublisherConfig;
public class CustomArtifactoryPlugin implements Plugin<Project> {
private static String MAVEN_PUBLIC_REPO = "/maven-public";
private String contextUrl = "MY_CUSTOM_REPO_BASE_URL";
#Override
public void apply(Project project) {
// Base gradle publishing plugin
// - maven plugin for pulishing java artefacts
// - ivy plugin if for publishing other type of artefacts: rpms, archives, ..
project.getPluginManager().apply(MavenPublishPlugin.class);
// project.getPluginManager().apply(IvyPublishPlugin.class);
// Apply the Artifactory plugin
project.getPluginManager().apply(ArtifactoryPlugin.class);
// Add Artifactory repo to the repositories
project.getRepositories().maven(new ArtifactoryAction(contextUrl + MAVEN_PUBLIC_REPO, "user", "password"));
// Configure artifactory plugin - using 'withPlugin' ensures that plugin has already been applied
project.getPluginManager().withPlugin("com.jfrog.artifactory", appliedPlugin -> {
// artifactory {
ArtifactoryPluginConvention pluginConvention = ArtifactoryPluginUtil.getArtifactoryConvention(project);
// contextUrl = "${contextUrl}"
pluginConvention.setContextUrl(contextUrl);
// publish {
PublisherConfig publisherConfig = new PublisherConfig(pluginConvention);
pluginConvention.setPublisherConfig(publisherConfig);
// repository {
pluginConvention.getPublisherConfig().repository(repository -> {
// repoKey = 'default-gradle-dev-local' ...
repository.setRepoKey("default-gradle-dev-local"); // The Artifactory repository key to publish to
repository.setUsername("${artifactory_user}"); // The publisher user name
repository.setPassword("${artifactory_password}"); // The publisher password
repository.setMavenCompatible(true);
});
// defaults {
pluginConvention.getPublisherConfig().defaults(artifactoryTask -> {
// publications('mavenJava')
artifactoryTask.publications("mavenJava");
artifactoryTask.setPublishArtifacts("true");
artifactoryTask.setPublishPom("true");
});
});
}
}
EDIT for the publication configuration, you can do as follows:
// create maven publication
project.getExtensions().configure(PublishingExtension.class, publishingExtension -> {
publishingExtension.publications(publications -> {
publications.create("mavenPublication", MavenPublication.class, mavenPublication -> {
mavenPublication.setVersion("1.0.0");
mavenPublication.setGroupId("groupId");
mavenPublication.from(project.getComponents().findByName("java"));
});
});
});
Related
I'm trying to add a -Pojo suffix to my generated jOOQ pojos.
The strategy implementation is straightforward enough:
package my.app.jooq.strategy
import org.jooq.codegen.DefaultGeneratorStrategy
import org.jooq.codegen.GeneratorStrategy
import org.jooq.codegen.GeneratorStrategy.Mode.POJO
import org.jooq.meta.Definition
class MyGeneratorStrategy : DefaultGeneratorStrategy() {
override fun getJavaClassName(definition: Definition, mode: GeneratorStrategy.Mode): String {
return when (mode) {
POJO -> super.getJavaClassName(definition, mode) + "Pojo"
else -> super.getJavaClassName(definition, mode)
}
}
}
but codegen just refuses to pick it up. (ClassNotFoundException).
According to https://groups.google.com/g/jooq-user/c/LM5ioRHNhJw :
you would have to create a separate project/module only for that strategy class, in order to create a dependency graph like so:
Code generation module... depends on
Strategy module... depends on
jOOQ libraries
so I did... jOOQ doesn't care.
PM org.jooq.tools.JooqLogger error
SEVERE: Error in file: /home/user/code/my-app/backend/db/build/tmp/generateMyAppJooq/config.xml. Error : my.app.jooq.strategy.MyGeneratorStrategy
java.lang.ClassNotFoundException: my.app.jooq.strategy.MyGeneratorStrategy
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at org.jooq.codegen.GenerationTool.loadClass0(GenerationTool.java:1075)
at org.jooq.codegen.GenerationTool.loadClass(GenerationTool.java:1005)
at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:405)
at org.jooq.codegen.GenerationTool.run(GenerationTool.java:233)
at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:228)
at org.jooq.codegen.GenerationTool.main(GenerationTool.java:200)
here's how the codegen module is set up:
plugins {
id 'nu.studer.jooq' version "${plugin_jooq}"
id 'io.spring.dependency-management'
}
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
mavenBom "org.jetbrains.kotlin:kotlin-bom:${fw_kotlin}"
}
}
dependencies {
api "org.postgresql:postgresql"
implementation project(":backend-jooq-config")
api "org.springframework.boot:spring-boot-starter-jooq"
implementation "org.jooq:jooq-meta"
implementation "org.jooq:jooq-codegen"
jooqGenerator "org.postgresql:postgresql"
}
jooq {
version = dependencyManagement.importedProperties['jooq.version']
edition = nu.studer.gradle.jooq.JooqEdition.OSS
configurations {
myApp {
generateSchemaSourceOnCompilation = true
generationTool {
logging = org.jooq.meta.jaxb.Logging.WARN
jdbc {
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql://localhost:5432/myapp'
user = 'user'
password = 'password'
properties {
property {
key = 'PAGE_SIZE'
value = 2048
}
}
}
generator {
name = 'org.jooq.codegen.DefaultGenerator'
strategy {
name = 'my.app.jooq.strategy.MyGeneratorStrategy'
}
database {
name = 'org.jooq.meta.postgres.PostgresDatabase'
inputSchema = 'public'
includes = '.*'
excludes = ''
}
generate {
daos = true
springAnnotations = true
}
target {
directory = 'src/main/java'
packageName = 'my.app.db'
}
}
}
}
}
}
I don't see what I'm doing wrong.
And yes, the strategy is being compiled:
find .. -name "*GeneratorStrategy*"
../backend/jooq-config/build/classes/kotlin/main/my/app/jooq/strategy/MyGeneratorStrategy.class
../backend/jooq-config/build/classes/kotlin/main/my/app/jooq/strategy/MyGeneratorStrategy$WhenMappings.class
../backend/jooq-config/src/main/kotlin/my/app/jooq/strategy/MyGeneratorStrategy.kt
how do I resolve this?
Fixing your configuration
There's an example here on how to set up this third party code generation plugin to use a custom strategy:
https://github.com/etiennestuder/gradle-jooq-plugin/tree/master/example/configure_custom_generator_strategy
As you can see, the dependency is specified as:
jooqGenerator project(':backend-jooq-config')
Not
implementation project(':backend-jooq-config')
Using a declarative configuration instead
For such simple cases, jOOQ also offers an out-of-the-box configuration called "matcher strategy," where it matches names and replaces them by something else. E.g.
generator {
strategy {
matchers {
tables {
table {
pojoClass {
transform = 'PASCAL'
expression = '\$0_POJO'
}
}
}
}
}
}
I'm trying to publish a jar to oss.sontatype.org using id 'maven-publish' (gradle 6.8.1).
Problem is that by default gradle publishes its module metadata and sonatype.org does not seem to like that. What happens is that sonatype does not list the jar artifact anymore. All I see (in the sontype ui) is:
myproject-SNAPSHOT-javadoc.jar
myproject-SNAPSHOT-source.jar
myproject-SNAPSHOT.module
The jar is missing although I can see in the gradle log that it uploads the jar.
If I disable the gradle metadata
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
I see the expected files:
myproject-SNAPSHOT-javadoc.jar
myproject-SNAPSHOT-source.jar
myproject-SNAPSHOT.jar
I wonder if it is possible to publish gradle module metadata to oss.sonatype.org?
Here is my publishing configuration on github and inline:
// does not work on oss.sonatype.org
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
publishing {
publications {
OpenApiProcessor (MavenPublication) {
groupId project.group
artifactId project.name
version project.version
from components.java
artifact sourcesJar
artifact javadocJar
pom {
name = project.projectTitle
description = project.projectDesc
url = project.projectUrl
licenses {
license {
name = 'The Apache Software License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution = "repo"
}
}
developers {
developer {
id = 'hauner'
name = 'Martin Hauner'
}
}
scm {
url = "https://github.com/${project.projectGithubRepo}".toString ()
}
}
}
}
repositories {
maven {
def releaseRepository = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2")
def snapshotRepository = uri("https://oss.sonatype.org/content/repositories/snapshots")
url = project.isReleaseVersion ? releaseRepository : snapshotRepository
credentials {
username = publishUser
password = publishKey
}
}
}
}
tasks.withType(Sign) {
onlyIf { project.isReleaseVersion }
}
signing {
useInMemoryPgpKeys(signKey, signPwd)
signing {
sign publishing.publications.OpenApiProcessor
}
}
My Plugin is loading before Vault, even tho I added a depend/load-after into the plugin.yml
I tried depend, softdepend and loadbefore. I even tried downgrading the on the server used version of Vault.
I tried even loadbefore without depend and the other way around.
My plugins.yml
name: TrainsaPlugin
version: ${project.version}
main: de.gamingcraft.trainsa.TrainsaPlugin
(...)
loadbefore:
- Vault
depend:
- Vault
commands: (...)
My Main Class:
public final class TrainsaPlugin extends JavaPlugin {
(...)
public static Economy econ = null;
public static Permission perms = null;
public static Chat chat = null;
#Override
public void onEnable() {
(...)
if (!setupEconomy() ) {
System.out.println("Disabled due to no Vault dependency found!");
getServer().getPluginManager().disablePlugin(this);
return;
}
setupPermissions();
setupChat();
}
private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return false;
}
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
econ = rsp.getProvider();
return econ != null;
}
private boolean setupChat() {
RegisteredServiceProvider<Chat> rsp = getServer().getServicesManager().getRegistration(Chat.class);
chat = rsp.getProvider();
return chat != null;
}
private boolean setupPermissions() {
RegisteredServiceProvider<Permission> rsp = getServer().getServicesManager().getRegistration(Permission.class);
perms = rsp.getProvider();
return perms != null;
}
#Override
public void onDisable() {
}
(...)
}
The Log
[22:35:43 INFO]: [TrainsaPlugin] Disabling TrainsaPlugin v1.0
(...)
[22:35:43 INFO]: Server permissions file permissions.yml is empty, ignoring it
[22:35:43 INFO]: Done (1,912s)! For help, type "help" or "?"
[22:35:43 INFO]: [Vault] Checking for Updates ...
I know, that my main-class disables my plugin when Vault is not found and i want that because it's essential at the moment.
TL;DR: My problem is, that Vault loads too late.
To your plugin.yml add depend: [Vault]
For more info see this
You added vault to loadbefore, which makes your plugin load before vault. If you want vault to load before your plugin, use depend: [Vault,someOtherPlugin,someOtherPlugin,etc].
I fixed it by adding
<scope>provided</scope>
to every dependency, that was a plugin in the pom.xml
I am trying to generate the .jar of my Gradle project but when it is generated using Maven publishing it is also generating a .pom file.
The problem is that I have another project that when it implements this dependency before it only looked for .jar and now it looks for .pom in all the others, what I want to do is that the project stops generating a .pom using the "publishing" task or that when implement it stop looking for the .pom files for the others to work.
Here is the code to generate the .jar in Artifactory project A with the one in project B that uses A and looks for the .pom:
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'com.proteccion.myproject'
artifactId = 'myproject-base'
version = '1.0.1'
from components.java
}
}
repositories {
maven {
name = 'artifactory'
url 'https://url/artifactory/MyProject'
credentials {
username System.getenv("ARTIFACTORY_USER")
password System.getenv("ARTIFACTORY_PWD")
}
}
}
}
repositories {
jcenter()
maven {
url 'https://url/artifactory/MyProject'
credentials {
username System.getenv("ARTIFACTORY_USER")
password System.getenv("ARTIFACTORY_PWD")
}
}
}
Perhaps with a Gradle equivalent of this segment:
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'com.proteccion.myproject'
artifactId = 'myproject-base'
version = '1.0.1'
from components.java
}
}
Finally this worked for me:
metadataSources {
artifact()
}
Forces to search only for the jar file.
The complete configuration:
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'com.company.myproject'
artifactId = 'myproject-base'
version = '1.0.1'
from components.java
}
}
repositories {
maven {
name = 'artifactory'
url 'https://url/artifactory/MyProject'
credentials {
username System.getenv("ARTIFACTORY_USER")
password System.getenv("ARTIFACTORY_PWD")
}
}
}
}
repositories {
jcenter()
maven {
url 'https://url/artifactory/MyProject'
credentials {
username System.getenv("ARTIFACTORY_USER")
password System.getenv("ARTIFACTORY_PWD")
}
metadataSources {
artifact()
}
}
}
Documentation (Example 18):
https://docs.gradle.org/current/userguide/dependency_management.html
Example 17. Maven repository that supports artifacts without metadata
repositories {
maven {
url "http://repo.mycompany.com/repo"
metadataSources {
mavenPom()
artifact()
}
}
}
I faced some magic behaviour in build.gradle configuration.
I'm trying to enable artifactoryPublish for project with subprojects.
I have the following structure
root
--subproj1
--subproj2
--common
gradle version 6.0.1
Case 1
on root level i have build gradle file with the following section
subprojects {
apply from: "$rootDir/gradle/artifactory.gradle"
}
in artifactory.gradle
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
artifactory {
contextUrl = artifactoryUrl
publish {
repository {
repoKey = 'mvn-snapshot-local'
password = artifactoryPassword
username = artifactoryUser
}
defaults {
publications('mavenJava')
publishArtifacts = true
publishPom = true
}
}
}
when i run artifactoryPublish it complete successfully but publish nothing
Case 2
when i move publishing section from file to top level like this
subprojects {
apply from: "$rootDir/gradle/artifactory.gradle"
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
everithing works fine, build successfull and publish.
Question
What is the difference in this 2 configurations, why it's not working in the 1 case?
I think would look more accurate if i keep all publishing related sections in one place rather then in different, but i can't by some reason.
It seems like the problem was that I missed plugin configuration:
pluginManagement {
gradle.ext.artifactoryPassword = artifactory_password ?: "nokey"
gradle.ext.artifactoryUser = artifactory_user ?: "nokey"
repositories {
mavenLocal()
maven {
url "${artifactoryUrl}/mvn-gradle-plugins"
credentials {
username = gradle.ext.artifactoryUser
password = gradle.ext.artifactoryPassword
}
}
maven {
url "${artifactoryUrl}/mvn-libs-release"
credentials {
username = gradle.ext.artifactoryUser
password = gradle.ext.artifactoryPassword
}
}
}
}
The repositories were configured in repositories section:
repositories {
if(version.toString().endsWith('SNAPSHOT')) {
maven {
url "$artifactoryUrl/mvn-libs-snapshot"
credentials {
username artifactoryUser
password artifactoryPassword
}
}
}
maven {
url "$artifactoryUrl/mvn-libs-release"
credentials {
username artifactoryUser
password artifactoryPassword
}
}
maven {
credentials {
password = artifactoryPassword
username = artifactoryUser
}
url "$artifactoryUrl/mvn-external"
}
mavenLocal()
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
But it hasn't worked until I added plugin management section and updated versions of artifactory and recon plugins.