I have 2 Kotlin library modules A and B, and B has...
# gradle
e
I have 2 Kotlin library modules A and B, and B has a dependency on A. I have code that I want to share between them, but I want it to be internal, and not published as a separate artifact. I make a top level directory containing that code with all of the visibility set to
internal
, and add that directory as a SourceSet sourceDir to both A and B. It works fine in A, but in B the IDE complains that the code is
internal
but it seems to compile fine. I'm hoping that the way Kotlin mangles
internal
code would cause there to not be redeclaration issues in consumers if they depend on both A and B, but the IDE errors are making me think twice about doing this. Should it be fine?
I tried making my shared code
public
and that resolves the IDE error. It also doesn't lead to any redeclaration issues since I guess the first one encountered gets used. So I imagine the problem here would be if there was a consumer using different versions of A and B and the behavior of the shared code changed.
t
it is a know IDE problem - for some reason it ignores
-Xfriends-path
argument. Will link an issue a little later
m
That issue aside, is sharing a source directory between 2 “compilations” (I want to say compilation but maybe it’s another term) supposed to work in the IDE? For an example if I have this in the shared code
Copy code
interface foo { fun bar() }
And 2 implementations in A and B, is the IDE aware of this?
The only way I got this to work reliably so far is using KMP and multiple JVM targets, which is deprecated
t
@mbonnin I would suggest you to open an KTIJ issue with repro
m
I don’t see how it could work conceptually speaking. As far as the compiler is concerned, it duplicates the sources, right? The compiler has no way to know the same file is used in 2 different modules
So to me it’s kind of “working as designed”. Or is there a way?
t
could you provide an more detailed example of your problem, so I can better understand it?
m
👍Sure, I’ll upload that in a bit
There are 2 modules:
moduleA
and
moduleB
. Both are calling
srcDir("../sharecCode")
. It compiles fine but looks like the IDE can only add
sharedCode
to a single module.
This is
BFoo
in the IDE
If I comment
srcDir
in moduleA then the symbol is recognized again in the IDE (but moduleA fails to compile)
t
let me clarify why we have this limitation on the IDEA side. For me it looks incorrect
👀 1
🙏 1
1
v
Yeah IntelliJ was never able to add the same source directory to multiple modules as long as I remember back. But imho this even is a good thing, because it blatantly shows that what your are doing is a really bad idea in practically all JVM language. :-D Unless A and B are mutually exclusive or it is 100% ensured that they use the same version, not only by artifact metadata, but at runtime. Because you end up with the same classes in two Jars, and that is always a bad thing to have on the classpath that causes various confusing issues. If you want to share code, you should really publish the shared code and be good. If you are using JPMS, you can use "exports ... to ..." to restrict who should be able to use a package. If you are using Kotlin, have the code in the shared module all be
internal
and put the shared module on the friend path when compiling A and B. In all other cases have "internal" in the package name and tell people "don't use internal stuff". It anyway is always just a nice try, but if someone wants to use it, there is some way.
👍 1
2
e
using a
@RequiresOptIn
annotation is about the same as using
internal
but without needing to mess with friend paths
👍 2
👌 1
t
@mbonnin answering your question - currently it is a limitation of Project representation in the IDEA which should be addressed kind-of soon. Though I fully agree with @Vampire here - using your approach may lead to unexpected side-effects and better to move shared code to separate sub-project.
@eygraber please track this issue for your problem
m
@tapchicoma Damn, I didn’t mean that to become my approach 😅 . I actually agree with you and Vampire here that it’s not great. I wouldn’t even try to support it in IDEA
should be addressed kind-of soon.
Is there a YouTrack or anything? I’m curious what can be done here. I’m tempted to say IDE support for this scenario is borderline impossible
t
this one (not sure if you will have an access to it)
1
m
Yup, I can access it 👍
(ah but not the Google Docs)
😅 1
t
in general it is required for different other use-cases and not just for this specific one
👍 1
m
The basic idea is to allow source files to exist in several resolve contexts
😮 wow
dreams of multi-android variant support in the IDE...