I have to add some kotlin-written classes at groovy-written shared library to use it in my jenkins pipeline. However, these classes aren't available:
WorkflowScript: 19: unable to resolve class package.name.KotlinClass
And i don't have the same problem with groovy classes. I think the problem is i don't declare any tasks like compileKotlin, but where should i declare it? What drives the building of sources from shared plugin libraries and is this process configurable?
If I understand the problem correctly, you have a shared library in Jenkins, which a pipeline makes use of. Within that shared library, you would like your groovy to call onto classes compiled from kotlin.
The best approach to this would be to have a separate process compile the kotlin and publish a JAR into a maven repository. Once that is done, your groovy shared library can fetch the JAR using #Grab. This is covered in https://www.jenkins.io/doc/book/pipeline/shared-libraries/#using-third-party-libraries and broadly works like so:
#Grab('org.apache.commons:commons-math3:3.4.1')
import org.apache.commons.math3.primes.Primes
void parallelize(int count) {
if (!Primes.isPrime(count)) {
error "${count} was not prime"
}
// …
}
If you want to resolve that JAR from your own private maven repository as opposed to Maven Central, you can also add the #GrabResolver annotation as documented here https://docs.groovy-lang.org/latest/html/documentation/grape.html#Grape-SpecifyAdditionalRepositories
#GrabResolver(name='restlet', root='http://maven.restlet.org/')
#Grab('org.apache.commons:commons-math3:3.4.1')
A problem you will run into here is that you cannot add credentials into that #GrabResolver and I am not aware of a way to get credentials into the groovy sandbox to make that work for Jenkins shared libraries.
An alternative approach, as hinted by Jenkins own documentation is to build the required functionality into it's own executable, and make sure that executable is available in the build process the Jenkins shared library is being called in.
Related
I am trying to build a kotlin library for discord bots, which can be found at https://github.com/TheDrone7/discord-kt , published to jcenter (bintray link - https://bintray.com/thedrone7/discordKt/discord-kt). The library has a few dependencies of it's own as well.
When I add my own library to my test app, the library's dependencies were not installed and I started getting some errors. Is there a way to specify the library's dependencies so that they get automatically installed when a user uses my library?
EDIT: -
So basically my test app's build.gradle.kts file's dependencies section is given below
dependencies {
// Use the Kotlin JDK 8 standard library.
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.theDrone:discordKt:0.0.1a")
// Use the Kotlin test library.
testImplementation("org.jetbrains.kotlin:kotlin-test")
// Use the Kotlin JUnit integration.
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}
And my library is dependent on the following packages: -
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0
org.java-websocket:Java-WebSocket:1.4.0
com.beust:klaxon:5.0.5
org.slf4j:slf4j-jdk14:1.7.26
now when I run my test app, it shows gives error that there is no class named WebSocketClient which is a part of the org.java-websocket:Java-WebSocket:1.4.0 package and is also the base of my entire library.
When I add the listed packages to my test app's dependencies, it works perfectly fine. So is there a way that I could define in my library that the apps using it will also automatically depend on the packages my library depends on?
You declared the Java-WebSocket library as a dependency of your library using the implementation configuration.
This configuration means: I need that for my code to work, but it's an implementation detail and it's thus not part of my public API, so users of my library won't have access to it in their compile classpath.
So Gradle, when it generates the pom.xml file for your library, adds Java-WebSocket as a runtime dependency, and not as a compile dependency.
Read the java-library plugin documentation, which explains all of that in details. Once you have understood it, use api instead of implementation in your library's build.gradle.kts file for the dependencies that are part of your API, and should thus be compile dependencies and not runtime dependencies:
api("org.java-websocket:Java-WebSocket:1.4.0")
In the Kotlin documentation they are mentioning some kind of module for instance in the documentation for the internal modifier.
However I couldn't find any definition of the term module itself. So what is meant by module?
A module is a set of Kotlin sources compiled together:
an IntelliJ IDEA module;
a Maven project;
a Gradle source set;
a set of files compiled with one invocation of the Ant task.
This is in the same docs article about visibility modifiers. :)
From the Kotlin's documentation, a module is a set of Kotlin files compiled together:
an IntelliJ IDEA module
a Maven project;
a Gradle source set
a set of files compiled with one invocation of the <kotlinc> Ant task.
That is #hotkey's, but I would like to complement this answer.
According to Andrey Breslav, the Lead Language Designer of Kotlin:
a Kotlin module maps one-to-one to IntelliJ's module (iml-file).
According to IntelliJ's documentation:
Modules allow you to combine several technologies and frameworks in one application. In IntelliJ IDEA, you can create several modules for a project and each of them can be responsible for its own framework.
When it comes to a Maven project or a command line compilation, Andrey states:
Each compiler run, by default, is a separate module: all the binary dependencies will be treated as being not in the module being compiled at the moment.
Also, a Gradle source set is a module, with the exception that the test source set can access the internal declarations of main.
This means that if you have different build flavors in your Gradle configuration resulting in different source sets, for production and debug versions for example, then an internal class from one source set would not be available to be used in another source set.
Per Kotlin language specification §10.2 Modules:
A module is a concept on the boundary between the code itself and the
resulting application, thus it depends on and influences both of them.
A Kotlin module is a set of Kotlin files which are considered to be
interdependent and must be handled together during compilation.
In a simple case, a module is a set of files compiled at the same time
in a given project.
A set of files being compiled with a single Kotlin compiler invocation
A Maven module
A Gradle project
In a more complicated case involving multi-platform projects, a module
may be distributed across several compilations, projects and/or platforms.
For the purposes of Kotlin/Core, modules are important for internal
visibility. How modules influence particular platforms is
described in their respective sections of this specification.
I think you might be referring to org.koin.core.module.Module
A Koin module is a "space" to gather Koin definition. It's declared with the module function.
val myModule = module {
// Your definitions ...
}
This documentation would be helpful in that case.
I am using Anypont Studio 5.3.0 and server runtime 3.7.0. I want to invoke a main() method from my component. Application is developed using Maven, SpringBoot and JPA. It sits in the jar file and have the following structure.
com
package
Application.class (with main method)
another package
Other classes
lib
other jars
META-INF
persistance.xml
MANIFEST.MF
Org
springframework boot loader and other spring classes.
when file arrives with file pattern that I detect with mule polling component I would like to invoke Java component in mule flow that has main class and all the supporting classes.
Thanks,
David
did you mavenize your Application? If yes, you can add that as a dependency in your mule project pom, which is also mavenize. But you need to make sure that the jars are added in your maven repository i.e. execute first "mvn clean install" to your java application. Otherwise, add the jars in you build path. When you are able to do those, you can create a spring bean or create a java component in mule where they could call your class with main() method.
I never came across this kind of production scenario where there is a need to call main method of java class in enterprise application. Are you sure you have only main method to access other classes, it should have initialize, spring way of injection etc. Simple answer to you question, create a mule java component and override onCall method to call Application(class).main. I will never do this kind of stuff [for sure it will give more problems based on what is being written in main method]. In general we will use main method invocation in desktop application. if possible work on (or let the application team to work on) jar file to have better initializing options
I am developing a library (JAR) that is meant to be used across many projects. I am using SLF4j for logging, and so I have declared the SLF4J API JAR to be a compile configuration.
When I'm developing this library locally on my machine, I'd like to run tests and see the output from all the SLF4J log statements. Or, outside of a test, it helps to add a temporary main(String[]) method to a random class and test functionality and log output as if the lib was an executable JAR. Since SLF4J's default binding is a No-Op (no output whatsoever), I have been getting by so far by adding the SLF4J Simple binding as a compile configuration dependency while I am developing & testing. Then, before I commit and publish, I simply remove the Simple binding as a dependency (since each developer who uses my lib should be able to select their own binding).
This is hacky and I know Gradle support custom configs, but I have yet to see a coherent example that could act as a guide. Ideally I'd like to define a custom dev configuration so that as a dependency I could have:
dependencies {
compile 'org.slf4j:slf4j-api:1.7.5'
dev 'org.slf4j:slf4j-simple:1.7.5' // Only used when running/testing locally
}
...but then ony the SLF4J API JAR gets added to my pom. Any ideas as to how to accomplish this? Perhaps Gradle already has such a concept built into it, or perhaps a custom configuration isn't even the right approach.
I am kind of new to PlayFramework 2 and can not figure out how to resolve play 2 application dependencies. I need to add dependency on a local module loaded in IntellijIdea, not a jar file or repository.
While adding module dependencies in Idea project setting works just fine and ide itself is able to resolve them (autocompletion, imports etc are working), when trying to run in play2, its compiler cannot resolve any dependencies.
I manually configured Build.scala (adding val appDependencies = Seq("" % "" % "")) but am puzzled as to what resolvers I should use. I cannot point to a jar file, as it is a work in progress and such a file should be updated too often. Doing so would defeat the whole purpose of managed dependencies.
Play's main build mechanism uses SBT, which needs to know how to find all sources required for the build. There are several options for this:
make your module an SBT project itself and publish it to your local ivy repository. However that might be somewhat complex at this stage, and would involve adding your local ivy repository to the resolvers and re-publishing every time you change something in the module
declare your module as a sub-project. Play's documentation describes the process of working with sub-projects, I think this is the way you'd like to try out since then the idea command on Play's console will generate the IntelliJ configuration for the main application and the module.