Maven: Programming to Interface Projects - java

I am wondering If it is possible to implement an interface project in maven as below.
Project-A and Project-B have same classes implements interfaces in Project-C.
Project-Z uses only Project-I(POM) which includes Project A,B,C as module.
I want to use profile mechanism so that either Project-A or Project-B's implementation will be used by Project-Z.
Please give me a simple example if you think it is possible.
Thanks.

You can use java SPI (Service Provider Interface) by which the two implementing jars declare the same service in the manifest. Using apps can do a lookup, iterate over them and pick one. (I did not find a simple example on the spot.)

Simplest way that comes to mind if you really want to do it with a maven profile, you could set a property with the classname in the profile. Then instantiate the class in this property at runtime.
<profile>
<id>a</id>
<properties>
<myproject.componentX.implementation.class>com.foo.bar.BazA</myproject.componentX.implementation.class>
seems perhaps strange why you'd want to do it at build time in the root pom .... maybe you plan on not changing it often. there are better ways, depending on what you plan to do.
could you explain in what cases you want to change it and why and how often?

Related

How to check if a java project has only interfaces and enum

I am trying to build a core module to be used across services, its collection of enum and interfaces with(without) default implementation only. Wanted to know if its possible to impose this rule either as part of mvn build or ci flow to check if someone has pushed a class in it. Being able to done at mvn would be preferred though.
Is this even possible? If yes can someone point me how?
Not sure which is the best way but I would suggest a custom rule on sonar/findbugs/checkstyle/pmd with the appropriate plugin.
Or a custom annotation processor that you use at compile time.

Java SE - Clever way to implement "plug and play" for different library modules

I'm trying to do something clever. I am creating a weather application in which we can replace the weather API with another weather API without affecting the code base. So I started with a Maven project with multiple modules.
I have a Base module that contains the Interface class and the Base class. The Interface class contains the calls to the APIs (all calls are similar, if not exact) and the Base class contains the properties to the APIs (again, all properties are similar, if not exact).
I have a module for each of the two weather APIs we are testing with plans to create more modules for new weather APIs as we grow the application.
Finally, I have created a Core module (includes main) to implement the specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch statement and enumeration. But I want to know if there is a more clever way to do this. Maybe using a Pattern? Any suggestions?
Here is a picture of the structure I have just described:
Here is the UML representation:
This is a learning process for me. I want to discover how a real Java Guru would implement the appropriate module and class based on a specified configuration.
Thank you for your suggestions.
I'm trying to do something clever. I am creating a weather application
in which we can replace the weather API with another weather API
without affecting the code base.
Without reading further down, this first statement makes me think about a plugin architecture design, but in the process of software design, decisions must not be rushed, the more you delay, the more information you have and a better informed decision can be made, for now is just an idea to keep in mind.
I have a Base module that contains the Interface class and the Base
class. The Interface class contains the calls to the APIs (all calls
are similar, if not exact) and the Base class contains the properties
to the APIs (again, all properties are similar, if not exact).
When different modules share behaviour/state, it is a good idea to refactor them and produce base abstract classes and interfaces, so you are on the right track, but, if there are differences, those shouldn't be refactored into the base module. The reason behind that is simple, maintainability. If you start adding if clauses or switches to deal with these differences, you just introduced coupling between modules, and you'll be always having to make changes in the base module, whenever you add/modify other modules, and this is not desirable at all.
This is reflected by the Open/Closed principle form the SOLID principles, which states that a class should be open for extension but closed for modifications.
So after you've refactored the common behaviour into the base modules, then each new API should extend the base module, as you did.
Finally, I have created a Core module (includes main) to implement the
specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch
statement and enumeration. But I want to know if there is a more
clever way to do this. Maybe using a Pattern? Any suggestions?
Indeed, making use of a switch, makes it work, but its not a clean design at all, for the same reason as before, when adding, modifying or removing modules, would require to modify this module aswell, and also this code can potentially break.
One possible solution, would be to delegate this responsability on a new component and make use of a creational design pattern like the Abstract Factory, which will provide a interface to instantiate components without specifying its classes.
As for the architecture, so far, the plugin architecture still makes sense, but what if the different modules extend the base contract adding more features? One option is to use the Facade pattern to adapt the module calls and provide an output that implements an interface that clients expect.
But then again, with the provided details, this is the solution I'd suggest, but the scenario should be studied carefully and in greater detail, in order to be able to assure that these are the right tools for the job, and commit to them.
In addition to Salvador Juan Martinez's answer...
To implement a plugin architecture Java's Jar File Specification provides support for service provider interfaces (SPI) and how they are looked up.
As of Java 1.6. you can use the ServiceLoader to lookup service providers. For Java 1.5. and less you must do it on your own or use a library. E.g. commons-discovery.
The usage is quiet simple. In your case put a META-INF/services/com.a2i.weatherbase.IWeather file in each plugin module.
In the Weather Forecast IO module the file should contain only one line
com.a2i.weatherforecastio.ForecastIO
The line must be the full quallified name of an IWeather implementation class.
Do the same for the other module and you can load the implementations via ServiceLoader.
ServiceLoader<IWeather> weatherServicesLoader = ServiceLoader.load(IWeather.class);
Iterator<IWeather> weatherServices = weatherServicesLoader.iterator();
Now it depends on your runtime classpath how many services will be found. Try to add and remove module jar archives from the classpath and run your application.
EDIT
I wrote a blog about a pluggable architecture with standard java. See http://www.link-intersystems.com/blog/2016/01/02/a-plug-in-architecture-implemented-with-java/
Source code is also available at https://github.com/link-intersystems/blog/tree/master/java-plugin-architecture
One solution is you have to define the common interface with all the identified common operations. The extensions/plugins need to implement that interface and have to provide the implementation to common operations.
You can use an abstract factory design pattern to hook up the exact implementation at runtime based on the input parameters.
Interfaces and abstract classes are always good in such scenarios, Thanks.

How to move hibernate related code to its own 'project' so I can share it?

If I want to be able to re-use my hibernate related code with multiple IntelliJ solutions, what should I do?
Should I move my models (with annotations) and Dao's and service classes to their own module?
How would I then be able to re-use this module/project with other intellij solutions?
I guess they would have to compile down to a seperate .jar right?
It is possible to configure an IDEA project to point to a module in an external location. So you could configure multiple IDEA projects to point to the same hibernate module. This is a solution for a one-man show, primarily (although see here about using a variable to make this location configurable).
In order to make this distributable and sharable among multiple developers, you are looking at building a jar out of one module, or if it has no particular meaning to any specific project, making a new project that has the code and produces the jar, which other projects then have as a library.
You can use Spring or Guice for dependency injection. Refactor your dao/services to use generic, so if your children modules don't share the same pojo you can still reuse all your hibernate codes (for dao and services) without any duplications (although you might want to make them abstract, in this case)

Implementing dynamic plugins in Java

I'd like to implement a dynamic plugin feature in a Java application. Ideally:
The application would define an interface Plugin with a method like getCapabilities().
A plugin would be a JAR pluginX.jar containing a class PluginXImpl implementing Plugin (and maybe some others).
The user would put pluginX.jar in a special directory or set a configuration parameter pointing to it. The user should not necessarily have to include pluginX.jar in their classpath.
The application would find PluginXImpl (maybe via the JAR manifest, maybe by reflection) and add it to a registry.
The client could get an instance of PluginXImpl, e.g., by invoking a method like getPluginWithCapabilities("X"). The user should not necessarily have to know the name of the plugin.
I've got a sense I should be able to do this with peaberry, but I can't make any sense of the documentation. I've invested some time in learning Guice, so my preferred answer would not be "use Spring Dynamic Modules."
Can anybody give me a simple idea of how to go about doing this using Guice/peaberry, OSGi, or just plain Java?
This is actually quite easy using plain Java means:
Since you don't want the user to configure the classpath before starting the application, I would first create a URLClassLoader with an array of URLs to the files in your plugin directory. Use File.listFiles to find all plugin jars and then File.toURI().toURL() to get a URL to each file. You should pass the system classloader (ClassLoader.getSystemClassLoader()) as a parent to your URLClassLoader.
If the plugin jars contain a configuration file in META-INF/services as described in the API documentation for java.util.ServiceLoader, you can now use ServiceLoader.load(Plugin.class, myUrlClassLoader) to obatin a service loader for your Plugin interface and call iterator() on it to get instances of all configured Plugin implementations.
You still have to provide your own wrapper around this to filter plugin capabilites, but that shouldn't be too much trouble, I suppose.
OSGI would be fine if you want to replace the plugins during runtime i.g. for bugfixes in a 24/7 environment. I played a while with OSGI but it took too much time, because it wasn't a requirement, and you need a plan b if you remove a bundle.
My humble solution then was, providing a properties files with the class names of plugin descriptor classes and let the server call them to register (including quering their capabilities).
This is obvious suboptimal but I can't wait to read the accepted answer.
Any chance you can leverage the Service Provider Interface?
The best way to implement plug-ins with Guice is with Multibindings. The linked page goes into detail on how to use multibindings to host plugins.
Apologize if you know this, but check out the forName method of Class. It is used at least in JDBC to dynamically load the DBMS-specific driver classes runtime by class name.
Then I guess it would not be difficult to enumerate all class/jar files in a directory, load each of them, and define an interface for a static method getCapabilities() (or any name you choose) that returns their capabilities/description in whatever terms and format that makes sense for your system.

Managing dependencies to multiple versions of a library in Java and Eclipse

In the Eclipse environment I have project A. A has dependencies to projects or libraries B and C. (does not make a difference if they are projects or libraries)
B has dependency on LibX.v1 and C has dependency to LibX.v2.
During runtime, A will need B.jar and C.jar. Also classes in B.jar will need LibX.v1 and classes in C.jar will need LibX.v2 .
Being the different versions of the same library, LibX.v1 and LibX.v2 has same classes, so it is possible that a class may be loaded from the wrong version of the library in the runtime, causing lots of trouble. How do I manage these kind of situations?
Kind regards
Seref
Really, you don't. Most Java classloaders don't give any guarantees about the order in which libraries will be loaded, so you really need to be sure not to duplicate dependencies on your classpath. I would check if B or C could be updated to a newer version, or if LibX is fully backward-compatible.
Edit: actually, I found something that may help you. It's called OSGi, and I haven't used it, but it seems like it might do what you're trying to do. Here is a link to an intro article.
you'll need to use a 'multiple classloader' mechanism (which is what OSGI is capable of). In such a scenario the classloader for class B can only see LibX.v1, while classloader C only sees LibX.v2.
You can it do it with OSGI, but OSGI is much more than this and it's not trivial to get started with.
another plug-in framework is JPF, which also offers more than just using multiple classloaders. i think they both use the principle of 1 classloader per plug-in (module, whatever, ...)
maybe have a look at classworlds. I think it's possible to do it with this library. the benefit is that it focuses on the classloading aspect. documentation is not so good. classworlds uses the notion of class realms. take a look at the API Usage example on the site.
i'll add an example here if i find one.
anyway, no trivial solution for this i think
solving it with dependency management is the best solution of course, but it's not always possible.

Categories

Resources