Do you know any workaround to use objects with Ser...
# getting-started
h
Do you know any workaround to use objects with ServiceLoader? It requires a non-arg constructor, otherwise it will fail:
Caused by: java.util.ServiceConfigurationError: Factory: Impl Unable to get public no-arg constructor
and
NoSuchMethodException: Impl.<init>()
j
You mean you want the
ServiceLoader
to find and return an implementation that is a singleton
object
? Not sure this can be done. But why not just make that object a regular
class
if the goal is to use a Service Loader anyway?
An option could be to load a "factory" via service loader (instead of the end object), and have that factory just return the
object
for this implementation
h
Exactly. Yes, but I want also to write some super plugins which do not need to use service loader. At the moment I use delegation and a variable, but this looks ugly too, and requires another variable. I already use a factory, but this could be an object too 😄
p
if your
object
has a defined interface, you could have the serviceloader load an implementation of the interface that delegates to the object (not ideal but workable)
j
My point is that the things that need to use the object directly can do so, and the things that need to load the object via service loader could do so by loading instead a factory for that object (not the final desired interface).
@phldavies but then what's the point of this compared to just making the object a class? If you're creating instances all the time anyway
p
Maintaining the singleton-state of the object while providing direct access to the interface of the service through the serviceloader (not requiring access via serviceloader to not operate through a factory) - it really depends on what the desired usage is though.
👍 1
j
Not sure what the overhead of such approach would be compared to simply using a 2-step loading process. Service loader to load the factory, and then
factory.getImpl()
that returns the object. No extra wrapper. I guess it depends on how much the object's interface is used compared to how much the service loader is used. But I would expect the service loader to be rarely used, probably once per application run
h
Ideally, it should work automatically when detecting this object is used by a ServiceLoader. Or with an annotation to make the object constructor public (for Java only, could be synthetic). I have a factory service, which is a class without config and needs to return a class (with configurated values) or an object, when no config is needed, both cases are valid. I use these plugins during runtime with the service loader or at compile time with a super plugin. So yeah, I guess there is no good workaround to use objects directly. Currently, I use a variable to fake an object.
p
What I did:
class LogViewerProxy : MultiClipboardTool by LogViewer
where LogViewer is my object, and MultiClipboardTool is my interface getting service loaded
https://youtrack.jetbrains.com/issue/KT-25892 (I see you’re already on this issue homer disappear)