Error Type com.github.ybq.android.spinkit.R is defined multiple times, because of aar library - android-gradle-plugin

I have integrated a third party SDK (aar file), which uses com.github.ybq.android.spinkit inside of it. This aar library, does not declare com.github.ybq.android.spinkit as gradle depency and this causes an issue, when we try to create a release version of our app:
Type com.github.ybq.android.spinkit.R is defined multiple times
Debug builds work without any issues.
What I have tried:
Exclude a com.github.ybq.android.spinkit from this aar file. This did not worked, because it seems that it does not support aar files. Here is my code:
​
implementation ('example.library#aar') {
exclude group: 'com.github.ybq', module: 'Android-SpinKit'
}
I know that it is a fault of library creator to build a fat aar with compiled library additionally. However, I can't just force them to change it...
Perhaps there is a way to somehow exclude Android-SpinKit from that AAR library?

Related

Skeleton for Kotlin/native multiproject with dll library for backend and frontend app using it

I'm trying to create a multiproject using Kotlin/native and gradle in IDEA that consists of:
A backend subproject library. I want to use this library in frontend Kotlin app and also produce a native DLL that can be later used in other software. I doubt I'll need any platform specific behavior -- the most I'll interact with the system is read, write and watch a file for changes.
A frontend jvm app in Kotlin using this library as required dependency. To be more precise I'm going to write a glfw app in Kotlin that will use this lib, but that's a detail you don't have to bother with.
I want to be able to:
build DLL on it's own
build an app that depends on library and rebuilds if needed when the lib changed.
I made a hyperlink trip over gradle docs, JetBrains examples and repos but I don't quite understand how to make a multiproject like that. Can someone provide a minimal working example of such a Hello World project?
Right now this works for me in the initial stage of the project:
Use gradle init with basic type and kotlin DSL to generate a wrapper project
Add 2 modules with New > Module > Gradle > Kotlin/Multiplatform and Kotlin/JVM. That should add include("...") entries to root settings.gradle.kts At this point those modules will be empty with a single build.gradle.kts scripts
Root build.gradle.kts can be deleted - both library and app use their own
In the Multiplatform library setup at least one target for example like that:
// rootProject/library/build.gradle.kts
// ...
kotlin {
jvm() // used by jvm app
sourceSets { /*...*/ }
}
Now there should be no gradle errors and IDEA will detect the project properly - refresh gradle configuration (CTRL+SHIFT+O)
Create source directories for each module (because the modules rn): IDEA should hint the names of corresponding source sets (src/<target>/<kotlin|resources> etc.)
So now just to link the app and library together in the the app's buildscript add the implementation(project(":library")) dependency
Of course don't forget to configure the library target for example using linuxX64("native") { binaries { sharedLib {/*...*/ } } } block in kotlin plugin when trying to generate a DLL
Now it should mostly work. The structure of a project I'm working on rn looks like that:

How to add dependencies to a kotlin library?

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")

Calling *.aar files (android library) in nativescript vue

I already create an .aar (android library) files in android studio and want to call/use it in nativescript-vue project.
I have placed the aar file in "app/App_Resources/Android/libs" folder.
Based on my reading, in typescript the way to call the method in aar files is by calling com.package.MyClass.
My question is , how to call it in .vue files. I have tried to call the method using the same approach but its produce an error :
Module not found: Error: Can't resolve com.package.MyClass
Can someone please help me on this.
Your help is very much appreciated.
You may simply place your AAR file in your App_Resources/Android/libs directory, CLI will pick it up at build time and the native APIs should be available at runtime within your project.
Try a clean build if you see errors, make sure the AAR is picked up. You might be able to verify it from the CLI logs. If you still see issues, make sure the class you are trying to access is public.
I'm not sure it's possible to use the android lib directly in the main project or not. In my way, I create a NS plugin that includes the .aar library, then add this plugin to the main project & use the methods defined in the .aar library without problem.
If you place the .aar library in the main project, you should check if that .aar library is installed by running tns build command & look at console log. If it's installed together with the project, that means you can use the lib method in .vue or any .js files.

How to add org.eclipse.swt (and other plugin dependencies) as an automatic Java9 module?

In order to be able to use my Eclipse plugin "treezCore" also as a Java9 module I created a module-info.java in my src folder.
Furthermore, I moved the Plug-in Dependencies from the Classpath to the Modulepath. I can see a module "org.eclipse.swt.3.106.1.v20170926" in the plugin dependencies:
However, I am not able to reference that module in my module-info.java. I tried
require org.eclipse.swt.3.106.1.v20170926;
require org.eclipse.swt;
require swt;
None of those options worked. The jar file \plugins\org.eclipse.swt_3.106.1.v20170926-0519.jar that is used by Eclipse does not contain a module definition and
jar --file org.eclipse.swt_3.106.1.v20170926-0519.jar -d
says that the module descriptor can not be derived. Also see
Unable to derive module descriptor for auto generated module names in Java 9?
If I download a newer version of swt.jar from
http://download.eclipse.org/eclipse/downloads/drops4/R-4.7.1a-201710090410/download.php?dropFile=swt-4.7.1a-win32-win32-x86_64.zip
I get following output that looks promising:
swt automatic
requires java.base mandated
contains org.eclipse.swt
contains org.eclipse.swt.accessibility
contains org.eclipse.swt.awt
contains org.eclipse.swt.browser
contains org.eclipse.swt.custom
contains org.eclipse.swt.dnd
contains org.eclipse.swt.events
contains org.eclipse.swt.graphics
contains org.eclipse.swt.internal
contains org.eclipse.swt.internal.gdip
contains org.eclipse.swt.internal.image
contains org.eclipse.swt.internal.mozilla
contains org.eclipse.swt.internal.mozilla.init
contains org.eclipse.swt.internal.ole.win32
contains org.eclipse.swt.internal.opengl.win32
contains org.eclipse.swt.internal.webkit
contains org.eclipse.swt.internal.win32
contains org.eclipse.swt.layout
contains org.eclipse.swt.ole.win32
contains org.eclipse.swt.opengl
contains org.eclipse.swt.printing
contains org.eclipse.swt.program
contains org.eclipse.swt.widgets
I also depend on org.eclipse.jface and could not find a seperate download for it.
=> Do I really have to wait for a new release of Eclipse that uses new plugin versions including module definitions?
Or can I somehow reference the old version of swt from the plugins folder, even if it does not include a module definition? I looked for an easy way to define an alias or a fallback dependency e.g.
requires ../plugins/org.eclipse.swt_3.106.1.v20170926-0519.jar as 'org.eclipse.swt'
or
requires org.eclipse.swt fallback ../plugins/org.eclipse.swt_3.106.1.v20170926-0519.jar
but module-info.java does not seem to support such a syntax.
I have about 20 plugin dependencies and do not want to manually download each of them (if it would be possible) and include them as external jar file. Nor do I want to hack the individual Manifest/jar files in the Eclipse plugin folder. There are many jar files I would need to alter and an update of Eclipse would break that hack.
I am using Eclipse for RCP and RAP Developers, Version: Oxygen.1a Release (4.7.1a), Build id: 20171005-1200
Edit
When using Version: Photon Milestone 4 (4.8.0M4) Build id: 20171214-1849, the error in module-info.java vanishes when using
require org.eclipse.swt;
and having the Plug-in Dependencies in the Modulepath.
However, my imports do not work yet, see following image. If I move the Plug-in Dependencies from the Modulepath to the Classpath, the imports work but the error in module-info.java reappears.
I created a min example at
https://github.com/stefaneidelloth/Java9EclipsePluginExample/tree/master/MyPlugin
and I filed a bug report at
https://bugs.eclipse.org/bugs/show_bug.cgi?id=529089
Related questions:
How to use 3rd party library in Java9 module?
Unable to derive module descriptor for auto generated module names in Java 9?
Force Eclipse (Helios) to use a newer version of SWT at application runtime
JFace libraries stand-alone download (not picked from Eclipse plug-ins)
New Keywords in Java 9
What you observe is tracked in bug 525660, which starts with the observation that all existing (OSGi) artifacts of Eclipse don't work as automatic modules, because Java 9 fails to derive a valid module name from jar filenames of the shape org.eclipse.swt_3.106.1.v20170926-0519.jar.
Since this was discovered too late to request improving the algorithm for automatic module name derivation, this can only be fixed by adding Automatic-Module-Name headers to the manifests of future releases.
This header is present starting from Photon M4 as can be seen in org.eclipse.swt_3.107.0.v20171205-0742.jar, containing:
Automatic-Module-Name: org.eclipse.swt

OSGI cannot link to native method via JNI at runtime

I am trying to use a method from a DLL in a OSGI-bundle. The DLL gets loaded correctly in OSGI, but I still get an java unsatisfied link error, the native method is not found!
When deployed standalone in Java only (no OSGI), the DLL gets loaded and run perfectly.
Here's what I did:
I generated a JNI bridge to my C++ compiled DLL through SWIG.
I specified the package name when calling swig.
I declared the dll inclusion in my Maven pom.xml xml element, which generates a correct Manifest file.
Loading of the DLL libraries is done without any errors / warnings
What truly puzzles me is that the symbols in the dll seem to not be found:
java.lang.UnsatisfiedLinkError: com.bmw.corona.components.sample.impl.generated.AdasDeconstructorJNI.swig_module_init()V
The problem is when coupling it with OSGI, I'm guessing somewhere in OSGI's ClassLoader.
The method in the dll seems to have a the correct signature :
_Java_com_bmw_corona_components_sample_impl_generated_AdasDeconstructorJNI_swig_1module_1init#8
with the following prototype in the generated SWIG file:
SWIGEXPORT void JNICALL Java_AdasDeconstructorJNI_swig_1module_1init(JNIEnv *jenv, jclass jcls)
I was triple-sure to check that the Manifest includes the Bundle Native instruction.
What am I doing wrong?
You may want to consult this wiki article: http://wiki.osgi.org/wiki/Dependencies_In_Native_Code
It is hard to tell from your description, but it sound like you have 2 native libs. One with the JNI entry points and the other with the real native function. The above wiki article discusses the dependencies from the JNI native lib to other native libs.
The problem was twofold. First, the methods weren't found do to Visual Studio 2010's method name mangling. I added a linker directive :
#pragma comment(linker, "/EXPORT:__Java_com_bmw_corona_components_sample_impl_AdasDeconstructorJNI_swig_module_init=_Java_com_bmw_corona_components_sample_impl_AdasDeconstructorJNI_swig_1module_1init#8")
It does take a bit of time for all the bundles (more than 100) to get up and running, and I do get a java.lang.NullPointerException: null the first couple of seconds after launch. Afterwards, everything seems to be working fine. And the nullPointerException is gone..