We are using a Jenkins Shared Library to centralize some code for all our (scripted) pipelines. Now we factored out some Groovy code into a .jar library (written in Kotlin, compiled to be Java 8 compatible). We published this library to our in-house maven repo and now want to use it in our Shared Libary.
We are using #Grab to load our library and up until that point it works like a charm. However we are getting NoSuchMethodError's. We pinpointed it down a bit, we are using OkHttp in our Kotlin lib. OkHttp internally uses Okio. When we call methods that internally call OkHttp-Code from our pipeline, everything is fine. However when the OkHttp-Code call Okio internally, we get a NoSuchMethodError.
We already checked the published .jar file, it contains the classes with the methods that seem to be missing. Does anybody have an idea what the issue could be?
While we are at it, we can't access environment variables set on Jenkins in our Kotlin library, is there a way we can fix this?
We figured it out. The problem was, that a Jenkins plugin used an older version of okio internally. Because plugins and shared libraries somehow share the same classpath, okio did not get loaded and the version from the plugin got used, therefore the class was not present.
We fixed this by repackaging all dependencies in our .jar, so package names would not interfere and we can make sure that our specified dependencies are being used.
Looking the dependencies here you have a few problems:
OKHttp - seems to expect some Android libraries
okio - depends on the Kotlin runtime
Any calls to these will result in method not found errors unless you find a way to make them available without causing problems in Jenkins
Related
Could not resolve io.mockk:mockk:1.13.2 for :shared:iosArm64Test Could not resolve io.mockk:mockk:1.13.2 for :shared:iosSimulatorArm64Test Could not resolve io.mockk:mockk:1.13.2 for :shared:iosX64Test
Found that MockK is only supported for jvm target - https://github.com/mockk/mockk/issues/950
But what i know is the unit tests we write on common shared module are meant to be run on local machine (mac/ windows) which do have have JVM installed.
Please can anyone add some light over here. Thanks
You can use mockk only in jvm test sources. If you write common code, and you have native targets, it won't work.
So, you can add jvmTest instead of commonTest and write tests in jvmTest that use mockk. However, that won't test your native code directly.
Setting up a full "KMP" / "KMM" project seems like overkill, as only the commonMain/commonTest directories would be filled.
All the other templates seem to be platform-specific.
Is there something like a "pure" Kotlin library template?
It would just be a module with only commonMain and commonTest. You would need at least:
A Gradle module
Kotlin config with multiple targets in that module
Common code folders
Whether you put the app code in the same repo or have the shared code in a separate repo is up to you. I'm not sure how much simpler you can make the config, though.
One issue I think you'll run into is the need for platform-specific code on iOS because there are different interfaces for concurrency than you might want for a Kotlin-friendly (I.E. Android) environment. Same for things like default params.
My-KMP-Library
│ build.gradle.kts
└───src
└───commonMain
└───kotlin
└───mynamespace
What makes it multiplatform are the targets you specify in build.gradle.kts.
I'm having a problem with usage of khttp library (which is supposed to work in Kotlin and provides equal to python's request's library features)
My build.gradle contains those strings:
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib"
compile "com.github.jkcclemens:khttp:-SNAPSHOT"
}
Project builds with success, but importing with import khttp doesn't work
In general, I'm using kotlin as framework to IOS project, and khttp is needed to connect to longpoll server. If khttp isn't supposed to work in my case so what are my options? Using it's sources aint good idea i think
Try using this:
compile "com.github.jkcclemens:khttp:0.1.0"
And add https://jitpack.io/ as a repository
I know that I might be necrobumping, but if anyone is looking for an answer, they wouldn't be able to get it from the above.
Khttp library is build for kotlin JVM and not native. If you take a look at the source code, you'll be able to notice that it's using Java's libraries for it to function, this for example.
That means that sadly you can't run it on iOS and any platform that doesn't run JVM, as khttp will only run on the JVM platform and won't be able to run on native because of missing libraries.
I'm trying to use Picasso with disk caching. To do so, I understand I need to include the okhttp and okio libraries. When I do so, I get the following:
compile 'com.squareup.okio:okio:1.0.1'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.squareup.picasso:picasso:2.3.4'
java.lang.NoSuchMethodError: No static method source(Ljava/io/File;)Lokio/Source; in class Lokio/Okio; or its super classes (declaration of 'okio.Okio' appears in /system/framework/okhttp.jar)
at com.squareup.okhttp.internal.DiskLruCache.readJournal(DiskLruCache.java:243)
at com.squareup.okhttp.internal.DiskLruCache.open(DiskLruCache.java:224)
at com.squareup.okhttp.Cache.<init>(Cache.java:146)
at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:74)
at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:51)
at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:41)
at com.squareup.picasso.Utils$OkHttpLoaderCreator.create(Utils.java:407)
at com.squareup.picasso.Utils.createDefaultDownloader(Utils.java:255)
at com.squareup.picasso.Picasso$Builder.build(Picasso.java:605)
at com.squareup.picasso.Picasso.with(Picasso.java:482)
This is with a brand new app.
Any ideas what's going wrong?
Switching to okhttp 1.6.0 seems to solve the crash. Although I'm still not able to get disk caching working
You can remove the Okio dependency, it's transitive.
The problem is that the L preview was improperly packaged and incorrectly exposed Okio on the system classpath. All crashes from this can be ignored completely as a function of pre-release software. The actual L release will not behave this way.
More details are available at https://github.com/square/okhttp/issues/967
I'm trying to package the Mac version of an open source application that I didn't write (I'm not much of a coder). I'm using py2app 0.6.4. The application builds on my system properly, but I'm unsure of what to list for the includes in the setup.py file.
The dependencies include qt4, PyQt, matplotlib, cherrypy, and sip.
When I looked at this article on handling PyQt applications, I noticed the dependencies were not listed simply as PyQt but rather *PyQt4._qt* etc. How can I determine what to insert in the includes statement from the code of the application?
When py2app runs, it's going to look at each of your scripts, automatically grabbing any modules or packages imported by your scripts. In many cases, this will suffice and you won't need to list anything in the includes variable. Some packages have extra files such as data files that aren't used by the import statement, but must be present for the package to run correctly. Then you need to explicitly include it so py2app will grab it as well. Try to use your app; if you get an error that some module or file isn't found then worry about putting it in the includes variable.