Guice API with separate implementations - java

I have been trying to design a software architecture with guice that allows for separate implementations by different teams in different regions.
The idea is like:
API-A ->
API-B -> API-Global
API-C ->
API Global has a bunch of classes (related to GraphQL) that should be non-interface shells of what needs to be implemented.
Because the region specific APIs depend on the Global package I can't have region specific code there. Is there a way to create guice bindings in an overall graph that the Global API can find through introspection for consumption?
I looked at Guice multibinds to do this but I am not sure that the best way to do it. I know this is possible using Spring but would really want to use Guice to do this.
Thanks.

The way OSGi and other frameworks handle this is to let each implementation come with a standardized file which contains meta-information (meaning the implementation class), and which Global-API can then find on the classpath to configure itself.
(Consider using a standardized framework instead of reinventing the wheel, but this is the general process which I have seen in these frameworks).

Related

Prevent Internals leaking into API

I'm looking for different ways to prevent internals leaking into an API. This is a huge problem because once these internals leak into the API; you can run either into unexpected incompatibility issues or into frozen internals.
One of the simplest ways to do so is just make use of different Maven modules; one module with API and one module with implementation. This way it is impossible to expose the implementation from the API.
Unfortunately not everyone agrees this is the best approach; But are there other alternatives? E.g using checkstyle or other 'architecture checking' tools?
PS: Java 9 for us is not usable, since we are about to upgrade to Java 8 and this will be the lowest supporting version for quite some time to come.
Following your checkstyle idea, it should be possible to set up rules which examine import statements in source files.
Checkstyle has built-in support for that, specifically the IllegalImport and ImportControl rules.
This of course works best if public and internal classes can be easily separated by package names.
The idea for IllegalImport would be that you configure a TreeWalker in checkstyle which only looks at your API-sources, and which excludes imports from internal packages.
With the ImportControl rule on the other hand you can define very detailed access rules for the whole application/module in a separate XML file.
It is standard in Java to define an API using interfaces and implement them using classes. That way you can change the "internals" however you want and nothing changes for the user(s) of the API.
One alternative is to have one module (Jar file) for API and implementation (but then again, is it an API or just any kind of library?). Inside one separates classes and interfaces by using packages, e.g. com.acme.stuff.api and com.acme.stuff.impl. It is important to make classes inside the latter package protected or just package-protected.
Not only does the package name show the consuming developer "hey, this is the implementation", it is also not possible to use anything inside (let's omit reflections at this point for the sake of simplicity).
But again: This is against the idea of an API, because usually the implementation can be changed. With this approach one cannot separate API from implementation, because both are inside the same module.
If it is only about hiding internals of a library, then this is one (not the one) feasible approach.
And just in case you meant a library instead of an API, which only exposes its "frontend" (by using interfaces or abstract classes and such), use different package names, e.g. com.acme.stuff and com.acme.stuff.internal. The same visibility rules apply of course.
Also: This way one does not need Checkstyle and other burdens.
Here is a good start : http://wiki.netbeans.org/API_Design
Key point : Do not expose more than you want Obviously the less of the implementation is expressed in the API, the more flexibility one can have in future. There are some tricks that one can use to hide the implementation, but still deliver the desired functionality
I think you don't need any checkstyle or anything like that, just a good old solid design and architecture should be enough. Polymorphism is all you need here.
One of the simplest ways to do so is just make use of different Maven
modules; one module with API and one module with implementation. This
way it is impossible to expose the implementation from the API.
Yes, I totally agree, hide as much as possible, separate your interface in a standalone project.

Converting Spring abstract factory pattern to scala

In Spring I have a controller, a service interface which provides the methods this controller can access. The controller invokes various implementation methods of the service.
To acheive same 'seperation of design' in scala is this the correct implementation :
Define the scala controller, define a scala trait which acts as the service interface. Define a new class which extends this trait and provides the implementations of the service. The controller will then instatiate this new class and call the various methods implementations of the service methods.
Is this good design or how Spring MVC is used in practice ?
As has been commented by others, 'good design' is a flexible concept depending on other factors. I shall not add to that discussion but offer an overview of our approach instead.
We started with a conventional Java & Spring webapp, although we chose Jersey instead of Spring MVC. Later, we recoded in Scala, which went well. We deliberately kept to a Java-like style Scala - this may be seen as uncool but it works well and is easy to train up new colleagues.
Then we decided to drop Spring, along with its XML and the whole shebang of transitive dependencies. This was easy because we already had a set of services and controllers that were all classes with constructor-injected dependencies (all TDD of course). All we had to do was write a new Bootstrap class that instantiates the services and controllers, supplying the necessary concrete classes in each constructor parameter list. Conveniently, the Bootstrap class is essentially a transliteration of the original Spring wiring into (quite simple) Scala. The Bootstrap class is started from web.xml when the app starts. (This approach will be familiar to anyone who has used Pico Container.)
In our case, we didn't need to use traits much in our service layers; clean design of concrete classes driven by TDD was sufficient. But our approach would also work well with pluggable abstractions for the services, if that were necessary.
Now we have a webapp with no XML except web.xml, purely in Scala so it's easy to navigate and modify, and with far fewer external dependencies. This worked very well for us.
"Good design" is quite subjective and the meaning of "good design" changes over time for each programmer. There are a few things that most people consider best practices, yet even best practices have conflicts. My personal opinion is that a programmer should continue to learn these best practices and more importantly keep molding his code until it reaches the best shape for that situation. That point however, where it's the 'best' shape keeps changing as the programmer keeps learning.
I can not tell you what "good design" design is in your case as I don't know the situation. On top of that, I am not you, so my "good design" is not the best for you. I would suggest you find it yourself with the help of some questions:
Who are you programming for?
How long will your code live?
Who will maintain your code?
Do you want to create automatic tests and are you willing to change your design for that?
Do you need more than one implementation of a single principle?
What style feels right for you at this point in time?
How often will the code change?
Do you want to take the future into account, or only create what is needed right now?
What libraries do you like to use?
How much time do you want to spend?

Resolve implementation of an API dynamically

We have a system where we wanted to consume the implementation of our interfaces in a separate jar. The scenario is clients consume our work and provide their own implementation to override default implementation.
The question is what is the best way to bind/wire the actual implementation classes into our system?
One way is let spring wire the dependencies. It is currently not an option since all clients are not using spring.
Looked into some options like resolving interface implementation classes using reflection. Not very happy with this solution.
Another good old option is configure the class name in one of the property and let clients configure it. It looks good.
But wanted to find some elegant option if available.
Also any idea how SLF4J / EL resolves their implementations automatically?
I'd suggest you to use SPI (Service Provider Interface).
It requires creating file that enumerates all available implementations of specific service. This may be annoying. Fortunately you can use this open source library that does this work for you: http://code.google.com/p/spi/
Perhaps the Reflections library is what you are looking for.
Reflections scans your classpath, indexes the metadata, allows you to query it on runtime and may save and collect that information for many modules within your project.
Using Reflections you can query your metadata such as:
get all subtypes of some type
get all types/methods/fields annotated with some annotation, w/o annotation parameters matching
get all resources matching matching a regular expression

creating reusable modules

I'm writing a big Red5 Java application for the web.
Red5 a Flash Media Server alternative that is java based and is written with the spring framework.
I want to have many versions of my application online, each with different behaviors and different classes enabled or disabled.
I'm looking for a way to convert my code into modules based code that will allow me to remove/add modules/features from the main application.
I know about OSGI http://www.springsource.org/osgi but it says that it needs a SpringSource dm server and I have no idea how it's gonna work together in red5 and it's seems very complicated to fully understand.
I don't have a good knowledge of spring framework in general, i work with it db-related and that's it. red5 uses it more extensively.
so can anyone please make any sense from this information ? is there something that can be done to divide my code to modules ?
any information regarding the issue would be greatly appreciated.
My preferred method of dealing with this kind of situation is Dependancy Injection (DI). Spring has a DI capability built in, for which a tutorial is easy to find online. However, Spring's DI is not as good, for many reasons, as that provided by Guice, which I would highly recommend. (The main advantage of Guice over Spring's DI in my opinion is type safety.)
DI is basically a mechanism for replacing class implementations at runtime. Rather than hard code dependancies into classes (by having a class construct other classes directly for example) you code them to have their dependant classes passed to them in their constructors. The DI framework will then pass the correct instances at runtime according to the configuration. Spring configuration can be done via annotations or an XML file, Guice uses a subclass of com.google.inject.AbstractModule.
So you could use different configuration files for the different instances of your application, and have them provide different sets of features for activation, or indeed different implementations of the same feature. If you set up the application to use this technique then the only thing that need differ between instances is a single configuration file.

Introduce per-customer personalization in java application

I've searched on internet and here on SO, but couldn't wrap my mind around the various options.
What I need is a way to be able to introduce customer specific customization in any point of my app, in an "external" way, external as in "add drop-in jar and get the customized behavior".
I know that I should implement some sort of plugin system, but I really don't know where to start.
I've read some comment about spring, osgi, etc, can't figure out what is the best approach.
Currently, I have a really simple structure like this:
com.mycompany.module.client.jar // client side applet
com.mycompany.module.server.jar // server side services
I need a way of doing something like:
1) extend com.mycompany.module.client.MyClass as com.mycompany.module.client.MyCustomerClass
2) jar it separately from the "standard" jars: com.mycompany.customer.client.jar
3) drop in the jar
4) start the application, and have MyCustomerClass used everywhere the original MyClass was used.
Also, since the existing application is pretty big and based on a custom third-party framework, I can't introduce devastating changes.
Which is the best way of doing this?
Also, I need the solution to be doable with java 1.5, since the above mentioned third-party framework requires it.
Spring 3.1 is probably the easiest way to go about implementing this, as their dependency injection framework provides exactly what you need. With Spring 3.1's introduction of Bean Profiles, separating concerns can be even easier.
But integrating Spring into an existing project can be challenging, as there is some core architecture that must be created. If you are looking for a quick and non-invasive solution, using Spring containers programmatically may be an ideal approach.
Once you've initialized your Spring container in your startup code, you can explicitly access beans of a given interface by simply querying the container. Placing a single jar file with the necessary configuration classes on the classpath will essentially automatically include them.
Personalization depends on the application design strongly. You can search for a pluggable application on the Internet and read a good article (for an example: http://solitarygeek.com/java/a-simple-pluggable-java-application). In the pluggable application, you can add or remove a feature that a user decides. A way for the pluggable application is using the Interface for de-coupling of API layer and its implementation.
There is a good article in here
User personalisation is something which needs to be in the design. What you can change as an after thought if the main body of code cannot be changed, is likely to be very limited.
You need to start be identifying what can be changed on a per user basis. As it appears this cannot be changed, this is your main limiting factor. From this list determine what would be useful to change and implement this.

Categories

Resources