Slackbot
07/30/2022, 9:13 PMMartin
07/30/2022, 11:08 PMsrc/debug/kotlin/**
2. expose an interface that you load using a ServiceLoader or some other reflection technique (I think log4j does this)
3. expose different artifacts engineering
, engineering::noop
(what you're currently doing)Martin
07/30/2022, 11:09 PMengineering
and use R8 to remove the calls in release builds, like you would remove calls to Log.d
Stylianos Gakis
07/31/2022, 11:45 AMengineering
module with loadKoinModules
exposing some interface impls which would then be taken and used here, but this resulted in koin not loading those at the same time, so the things provided from engineering
were not picked up in time😅 So I wanted to move the engineering module in my main startKoin{}
to load them at the same time like I now do here. So since that is called from scr/main I have to have access to it, and have it do nothing in prod. I asked about this here to see if I could fix it on the koin part though.
2. Ngl this sounds like some magic, I don’t even know where I’d start with smth like that so I’m thinking I’ll skip if I got other options 😄
3. Yeap, this is what I am doing right now.
4. The r8 option does sound very interesting, but could I then “remove” the entire module using r8? What about the call here, what would this then do 🤔 I understand with Log.d it can just not call it, but here since I’m constructing a list, how would r8 work to make this work? I’d guess it’d have to look somewhat different.Martin
07/31/2022, 12:38 PMengineering-api
is the one that you depend on in your app and defines an interface
• engineering-impl
is the one you add to "debugImplementation"
• engineering-noop
is the one you add to "releaseImplemenation"
And then retrieve the implementation by reflection. This is not that different from 3 except that you get a bit more tooling because there is now a "contract" of what "engineering-api"
is and IntelliJ will tell you what methods are missing in "engineering-noop"
to satisfy the contractMartin
07/31/2022, 12:46 PMsince I’m constructing a list, how would r8 work to make this work?Not super familiar with koin but I guess you could do this:
val myModules = mutableListOf(
...
)
appenEngineeringModules(myModules)
modules(myModules)
And remove appendEngineeringModules
with R8Martin
07/31/2022, 12:48 PMasm
if you wanted to... Certainly a lot of trouble and will start to feel like magic to someone not familiar with the codebase though...Martin
07/31/2022, 12:48 PMStylianos Gakis
07/31/2022, 1:14 PMMartin
07/31/2022, 1:15 PMengineering-api
module will be an interface, it will not have any constructor. The constructor is what you need to get by reflection.Martin
07/31/2022, 1:15 PMMartin
07/31/2022, 1:18 PMStylianos Gakis
07/31/2022, 1:59 PMStylianos Gakis
07/31/2022, 8:33 PMMartin
07/31/2022, 8:42 PMMartin
07/31/2022, 8:43 PM:engineering-noop:build
and check whether something's missing without having to compile your app in release modeStylianos Gakis
07/31/2022, 8:50 PM./gradlew :engineering-noop:build
I guess I get this benefit after I make sure I am implementing that interface of course, I could in theory declare smth on an -api module and forget to do it on the -noop one and it’d still build, but I guess we can’t have it all 😄
Thanks so much for talking me through this btw, I really appreciate it!
As a side note, I’d still be curious to see how one would do this with reflection as you hinted before, not for my use case since I am good with what I’ve done now already, but for educational purposes 😄 If you do have some sample in mind I’d love to see it, if not no worries, I look for smth myself.Stylianos Gakis
07/31/2022, 8:52 PMhere▾
this▾
Martin
07/31/2022, 9:40 PMIf you do have some sample in mind I’d love to see it, if not no worries, I look for smth myself.I don't have a lot of samples at hand but I'm pretty sure this is how log4j does it (but I never looked really deep as that codebase is quite the beast): https://logging.apache.org/log4j/log4j-2.3.2/manual/extending.html All in all, it relies on a resource file with a fixed name under
META-INF
that contains the name of the implementation to load reflectively.
This allows to change the logging at runtime to something that logs to a remote server or to /dev/null depending the use casesMartin
07/31/2022, 9:43 PMMartin
07/31/2022, 9:45 PMMartin
07/31/2022, 9:46 PMStylianos Gakis
07/31/2022, 9:49 PMMartin
07/31/2022, 9:52 PM