Inject implementation of interface from dependent (plugin) JAR? - java

I have an interface A with a method Result doAction(Param param). I have a Spring application that will use implementations of the interface and call doAction() on it.
But the application does not define an implementation itself. The idea is that other people can provide their own implementations of the interface in JARs (plugins), the main application will pull those in as dependencies, and call doAction() on the JAR's implementation.
Any idea how I can do this in practice? The ideas I had were:
Try to autowire the implementation through Spring Boot, but for that I would need to know its package and add it to the component scan. So it would mean putting requirements on the naming of the "plugin" jar. Something I would prefer not to do.
With plain Java my first idea was to keep a registry of implementations (e.g. a Set<Interface A>), but the plugin wouldn't be able to access the registry -- it would be a dependency cycle.
What I'm doing right now is defining a Rest API that the "plugin" needs to implement, deploy the plugin in the same environment and the main application just makes the calls through the Rest API.
But for performance reasons I'm looking for a solution with more direct calls that doesn't involve communication over the network. Any suggestions?

Related

What's the proper way to share the interface?

What if I have a project that relies on the abstraction(interface) but does not contain any implementation for this interface. Therefore I want to give that interface to someone who can implement it so I (or someone else who is going to use my software) will be able to use their implementation of my interface.
Thus, I have the following question. How can I, let's say, share that interface?
The idea which came to me is to make JAR which contains interface and give it to someone who is going to implement that interface in JAR. After it, the one who implemented the interface, creates his JAR and gives it to me. So I can use his JAR with the implementation of my interface. Is it a proper way to do so?
The purpose of it is to make modular architecture so that if I need a new game(according to the above example), I'll take a JAR with implemented interface and just plug it in my project.
Yes.
You should have a shared build artifact (JAR file) that contains only the interfaces, which your project and the implementing project can both depend on.
You may want to look into tools like Maven or Gradle for helping orchestrate your build process with dependencies like this. For example, you may want to publish your API JAR to a shared package repository that both developers can work with.
You may also want to look into java.util.ServiceLoader and the Service Locator pattern, for discovering which specific implementation(s) you have available.

Use mock service in Seam project

I'm redesigning an improvement of a platform that already exists developed with Seam framework version 2.1.1.RA2, Java 6 and JBoss 4.2.3.GA and Ivy. I have 4 modules that communicate with each other. I want to modify one of these modules independently of others. I just want to know how to make a simulation of one module using the mock service.
Using beans.xml file you can add alternatives to your project. My suggestion is to use one interface with method definitions and make one bean with real implementation and one with mock implementation. In beans.xml just specify that you want to use class with mock implementation.
http://seamframework.org/Documentation/WhatIsBeansxmlAndWhyDoINeedIt.html

Java Dependency Injection with Multiple Implementations

My question: is there a way to use javax.inject (or any other Java injection framework) for a consumer of a Provider to use multiple implementations at runtime if the number of implementations is unknown at build time?
Some background on my need for this: I work on reusable frameworks which, for the most part, combine the use of a factory and a service locator to load implementations. Several of these seem like they could be reworked to use proper dependency injection, at least insofar as removing the service locator, but there are some that require loading all implementations found on the class path. This is achieved through a simple "multi-implementation" implementation which then loads the other implementations, saving the instances off in a collection and looping over them when the API is called.
I assume you are running on the Java SE platform (as opposed to a Java EE platform) in which case I would highly recommend HK2 (see https://hk2.java.net/2.2.0/). It has a lot of support for efficiently instantiating services and it is certainly the case that multiple implementations of the same contract can be available at runtime. Then at runtime there are a whole manner of mechanisms that you can use to choose which particular implementation will satisfy the dependency (i.e., service ranking or assisted injection etc)
For build time with hk2 you can create "inhabitant" files that describe services to the point where they can be satisfied at runtime without classloading all of them (only the one that is picked will be classloaded if you do it properly). This can be a huge performance boost at boot time of your application (if that sort of thing matters to you).
If you are running on a Java EE platform you can also use HK2, but you should then also give a long look at CDI. Both CDI and HK2 are implementations of JSR-330, and so both work with javax.inject API
So you basically have one implementation that delegates a call to an API method to all other implementations. you will need to inject this bean in all the dependencies you can do this in spring by giving this bean (this implementation instance) an id and then inject it using #Autowired #Qualifier("bean_id"). now for listing all implementations that can be done easily in spring by injecting an applicationContext into your delegate implementation and then querying the applicationContext for all beans implementing the API interface.

Guice: When to kick off injection/bootstrapping in a headless JAR?

So I'm writing a bunch of components (that will be packaged as JARs), and they are all using Guice for DI. These components are just reusable, "commons"-type JARs that will be used by other downstream projects.
My understanding with Guice is that you implement a concrete Module and use that to bind objects together and, in effect, configure all of your DI. It is also my understanding that you should then have a single "bootstrapping" phase where the Guice injector is created, and then all dependencies the module is configured with are then fetched from that injector with injector.getInstance(SomeClass.class).
That would work great in standalone application, that had some entry point, where you could invoke an init()-style method to then bootstrap Guice with, but in a headless JAR that has no entry point, I'm struggling with trying to determine when/where/how to bootstrap Guice.
These will be JARs living on the classpath and, at any point in time, an external entity could invoke and class and any method inside of them. I thought about using up a "lazy initialization" set up, where a method checks to see if its dependencies have been configured yet, and, if so, kicks off a bootstrap method.
But that's a really terrible solution! Partly, because that would require every class to have its own Module (which is ridiculous), and it would also pollute my entire codebase with DI-related code.
I'm clearly missing some Guice fundamentals here, otherwise I don't see how Guice could be used in anything other than an app where execution from start to finished is known and controlled. Any code samples are a huge plus! Thanks in advance.
If other code wants to configure your classes without using Guice, it should be able to. However, you should provide a Guice module which binds everything in a reasonable way so that other code (perhaps other modules) can install your module, and then inject the dependencies into their own classes.
Of course, you don't need to expose a module yourself at all - you can leave it up to others to perform all the binding. However, you may wish to provide a module to avoid exposing your implementation details - you can expose a public interface and a public module, but then keep the implementation package-private. The module can bind the interface to the implementation without the caller knowing anything about it.
You may also want to investigate private modules, so that you can bind dependencies that your code needs, without exposing them more widely.
Something, somewhere is going to have to create an injector - but if your code is just "library" code, then it almost certainly shouldn't be you. You shouldn't be performing the injection yourself - you should just be making your code amenable to injection.

java question on jar dependencies

I have a project that its main part (e.g. main.jar) depends on libraries (e.g. u1.jar, u2.jar etc) that has been created as distinct separate projects.
So one could reuse the library elsewhere i.e. there is no dependency between the utility libraries and the main part.
The main part has dependencies on the libraries of course but this is ok.
Now I need to add a specific functionality in one of the libraries.
The needed functionality is already implemented.
It is implemented via a spring bean and the user can configure how the implementation will behave at runtime.
The spring application context is created and used only via the main project and so I do not have access to the spring context
from the utility libraries.
The problem is that I would like to reuse this implementation (and not duplicate the code) and it is not possible to move that part elsewhere
What comes to mind is to create a dependency in this specific util jar to refer to the main.jar.
I will do this to be able to have access to the spring context from the utility jar as well.
What concerns me is that now, I have a cyclic dependency between main.jar and util.jar.
I.e. main.jar already depends on util.jar and now I will create a reverse dependecy as well.
Is this a good idea to do it? Or am I into trouble (class loading issues etc)?
Is there a nice approach for these kind of issues?
Thanks
create an interface and let util.jar work with interface with main.jar passing the implementation which simply wraps this context?
cyclic dependency looks like a nightmare. Which one will you build first?
Once you see that you have cyclic dependency, you know that you have something wrong in the design. Have you thought about if you can apply the Observer Pattern ? Or try to read this one about Acyclic Relationships

Categories