Discovering koin modules in classpath - koin

I'm designing an application that needs to support different feature sets in different deployments. I would like to build it in such a way that different feature implementations would be packaged into different jars. Depending on the actual jars in the classpath, respective features would be automatically discovered and activated by the microkernel.
I am looking to use Koin as the microkernel framework for the features autodiscovery. I like the fact it is very lightweight, native to Kotlin, and offers a great support for configuration and dependency management.
However, there does not seem to be support in Koin for modules autodiscovery via the classpath, and I wonder if I am missing something and there is a way to have modules automatically picked up?
I'm going to post my own 'pragmatic' solution which does not seem particularly Kotlin-esque, so would welcome welcome suggestions for better way of doing this!

The design I'm using is a classic for Java and relies on java.util.ServiceLoader. Each jar will have a file in /META-INF/services, which will contain a name of a class implementing ModuleProvider interface for that jar. The interface is defined as follows:
interface ModuleProvider {
fun buildModule(): org.koin.core.module.Module
}
My microkernel bootstrapping routine now looks like the following:
fun main() {
val app = startKoin {
environmentProperties() // allow system properties to be injected
modules(ServiceLoader.load(ModuleProvider::class.java).iterator().asSequence().map { it.buildModule() }.toList())
}
// rest of bootstrap
}
This works, but I can't help thinking that there must be a more elegant way, because surely I am not the only one with the need for module autodiscovery. Would appreciate suggestions!

Related

Extending external module with d.ts in typescript

I am building a nodejs application using typescript. I'm using several external libraries like express.js. As many, this library as well designed to be extendable.
I'd like to extend it by adding a custom method. What is the typescript best practice to do so?
I wanted to inherit a class from it, but its d.ts doesn't define any classes (obviously). I can extend the interface:
declare module Express {
export interface Application {
foo();
}
}
but I cannot figure out how to actually implement it.
Any help would be appreciated.
You shouldn't add members to Application directly unless you want to make a reusable library that other people should use. If that is indeed the case you will need function interception (http://basarat.github.io/this-and-prototype/#/apply).
I recommend just making a utility function.

Xpages - Java - How to start writing code

I am new to Java but not Lotus Notes. Here are some of my questions:
Main method in Java class - Can I run a simple HelloWorld.java in DDE as I would in Ecplise?
Do I use Java design element or create Java classes in project explorer?
Would it be better to uninstall other JVMs before starting on working Java in DDE?
Thanks
Arun
I strongly recommend you to invest some time to learn how Xpages and Java are used in DDE/Notes/Domino as:
the JVM of IBM is completely separated from other JVM you may have installed
Java classes don't have a main method - except you refer to those that come from an Agent
if you create a Java class for an XPages app you always use the Java class element
A good point to start is David Leedy's NotesIn9 series. You can check the whole compendium of video tutorials here: http://www.mindmeister.com/de/280533435/notesin9
If you just want to play with Java (not the XPages part) create a Java project in Domino Designer (change to the Java perspective) and then use the main to write code. When you run it as a Java program it will output to the console. You can still access Domino objects. For example, the code below shows how to do that... I did this to test out some data models and concepts and then copied the code to an actual NSF for use as a bean after I proved out my concept. It is so much easier to experiment and test running your code as a Java program and viewing the output in the browser.
Howard
public static void main(String[] args) {
try {
NotesThread.sinitThread(); // start thread
Session s = NotesFactory.createSession((String) null, (String) null, "cessna");
//do whatever
} catch (Exception e) {
e.printStackTrace();
} finally {
NotesThread.stermThread(); // must terminate every thread
}
}
As you tagged your question with XPages my answer will cover only Java development in DDE for XPages.
You can't use the main method as usually. Create a HelloWorld.java with a static methode hello() and call this method in an XPage with {javascript:com.package.HelloWorld.hello()}
You can use Java design elements. Those are easy to access in DDE and included in build path already. For larger projects you can create your own directory structure in Package explorer and include those in build path. As long as they included in build path you can use them in XPages.
The JVM is included in and get used from Domino server. You don't need to uninstall JVM on your computer.
I'm not sure what you mean by not wanting to run the whole program. The "program" is the same XPages runtime you'll have been running when writing SSJS. The JVM is created as part of that runtime, for a specific NSF. That runtime includes all the relevant OSGi plugins on which a lot of your Java code will depend (thinks like FacesContext classes, ExtLibUtil etc). Testing of "the program" in XPages is usually no different to testing of "the program" in traditional Notes development.
You can test from Eclipse, but you need to be able to connect to a Domino server in order to run the code in a similar way to how you need to be able to connect to a Domino server to run the debugger. So if running the debugger is an issue, running from Eclipse is a non-starter.
From Eclipse, unless you're running code from a OSGi plugin, you'll still need to copy and paste your code outside the NSF, unless you use test cases within the ODP.
If you want to run junit tests, an OpenNTF project is available for that. But from my experience of Java and junit testing, I don't think I would have been capable of using that to test my code when I was just starting out with Java. So it's not something I'd recommend.
Static methods (utility methods that are not in a managed bean) can be tested from standalone XPages. I've used that method before. Otherwise, beans can be added to a standalone XPage pointing to whatever data you wish or initialised with whatever values you wish, so you have the control to test part of it, if the application architecture allows it.
Check for the article "the double headed beast" from Bob Balaban. It explains the approach you want to take. While it was written for agents it applies to Java too.
What you need to do: write your businesses logic (the part you want to unit test) without dependencies to xpages specifics. Hand over the key objects in method calls: session database. You can initialize them in a main routine.
I wrote an article about that, Check it out.

Dynamics CRM 2011 - Does each plugin that related to a different entity have to have it's own assembly?

I am creating a series of related plugins. Each plugin is for a different entity. Does each plugin have to have it's own assembly? I'm using Visual Studio and I created a second project within the same solution but I can't see the new step in registration tool.
Thanks
It can do, but doesn't have to. That is pretty much your design decision. Consider if you had several classes all implementing IPlugin
public class MyFirstPlugin : IPlugin
{
//implemented as per usual
}
public class MySecondPlugin : IPlugin
{
//implemented as per usual
}
If you were to register that DLL in the plugin registration tool, you would see the following structure:
- Server
- DLL
- MyFirdtPlugin
- MySecondPlugin
You can then add steps to each plugin as desired.
The alternative would be to have one plugin per DLL, which would give you
- Server
- DLL1
- MyFirstPlugin
- DLL2
- MySecondPlugin
I must admit it seems like overkill - but it can also depend on how you are using your solutions.
In addition to glosrob's answer, I'm guessing that you're using the plugin registration tool to register your plugin. If so, you'll need to make sure that after you add your new plugin to the same dll, that you update the plugin dll itself with the registration tool, so you can register the new plugin method that you've created.
Yes, you can create each plugin in a different class library project but this is not a good practice. I'd prefer to collect all plugins into one class library.
Note that after selecting your assembly from the File Dialog you have to click on Load Assembly button to load all classes which implement the IPlugin interface.
To answer the question - no, each new plugin doesn't have to be contained in a new assembly.
To elaborate - it's technically possible to put in all the plugin code in just one project and a single file.
To warn - the above would be a nightmare to manage with all the ifs and buts, so it's a good example of can-but-shouldn't.
To suggest - I usually have a separate project for each entity's plugin and handle all the messages using a switch. On occasion, I might have two or three assemblies but you'll know when it's time to do so as you get there. Usually, one DLL is just enough.

How to modularize an Enterprise Application with OSGi and EE6?

I know that there are already some questions related to this topic but I couldn't find a real solution yet.
Currently I am developing applications with EE6, using JPA, CDI, JSF. I would like to take a more modular approach than packaging everything into a WAR or EAR and deploy the whole thing on an Application Server.
I am trying to design my applications as modular as possible by separating a module into 3 maven projects:
API - Contains the interfaces for (stateless) services
Model - Contains the JPA Entities for the specific module
Impl - Contains the implementation of the API, mostly CDI beans
The view logic of every module is currently bundeled within a big web project, which is ugly. I already thought of web fragmets, but if I spread my bean classes and xhtml files in jar files, I would have to implement a hook so that the resources could be looked up by a parent web application. This kind of solution would at least enable me to have a fourth project per module that would contain all the view logic related to the module, which is a good start.
What I want is not only that I can have those 4 kinds of projects, but also that every project is hot swappable. This led me to OSGi, which was at first really cool until I realized that the EE6 technologies are not very well supported within an OSGi Container.
JPA
Let's look at JPA first. There are some tutorials[1] around that explain how to make a JPA enabled OSGi Bundle, but none of these tutorials shows how to spread entities into different bundles(the model project of a module). I would want to have for example three different modules
Core
User
Blog
The model project of the blog module has a (compile-time)dependency on the model project of user.
The model project of the user module has a (compile-time)dependency on the model project of core.
How can I make JPA work in such a scenario without having to create a Persistence Unit for each model project of a module? I want one persistence unit that is aware of all entities available at runtime. The model projects in which the entities are should of course be hot swappable. Maybe I will need to make a separate project for every client that imports all the needed entities of the projects and contains a persistence.xml that includes all necessary configuration things. Are there any available maven plugins for building such a projects or even other approaches to solve that issue?
CDI
CDI is very nice. I really love it and I don't want to miss it any more! I use CDI extensions like MyFaces CODI and DeltaSpike which are awesome!
I inject my (stateless) services into other services or into the view layer which is just great. Since my services are stateless it should not be a problem to use them as OSGi Services, but what about CDI integration in OSGi? I found a glassfish CDI Extension[2] that would the injection of OSGi Services into CDI beans, but I also want may OSGi Services to be CDI beans. I am not totally sure how to achive that, probably I would have to use the BeanManager to instantiate the implementations and then register every implementation for its interface in the ServiceRegistry within a BundleActivator. Is there any standard way for doing that? I would like to avoid any (compile-time)dependencies to the OSGi framework.
I would also like to use my services just like I use them right now, without changing anything(implementations not annotated and injection points not qualified).
There is a JBoss Weld extension/sub project[3] that seems to target that issue but it seems to be inactive, i can't find any best practices or how-tos.
How can I leave my implementation as it is but still be able to use OSGi? I mean it would not be a big deal to add an annotation to the implementations since every implementation is already annotated with a stereotype annotation, anyway I would like to prevent that.
JSF
As mentioned before I would like to be able to spread my view logic module wise. As far as I know this is not really possible out of the box. Pax Web[4] should solve that somehow, but I am not familiar with it.
I would like to have a project "CoreWeb" in the module "core" that contains a Facelet template, let's call it "template.xhtml". A JSF page in a project called "BlogWeb" in the module "blog" should then be able to reference that template and apply a composition.
To be able to extend the view I would introduce a java interface "Extension" that can be implemented by a specific class of a module. A controller for a view would then inject all implementations of the extension. An extension would for example provide a list of subviews that will be included into a main view.
The described extension mechanism can be implemented easily, but the following requirements must be fulfilled:
When adding new OSGi Bundles to the application server, the set of available extensions might change, the extensions must be available for the controller of the view.
The subviews(from a separate bundle) which should be included into a main view should be accessible.
The concept of a single host but multiple slice applications of Spring Slices[5] is very interesting, but seems limited to Spring DM Server and the project also seems to be inactive.
Summary
After all the examples and behaviors I described I hope that you know what I would like to achive. It's simply an EE6 App that is very dynamic and modularized.
What I look for at the end is at least documentation on how to get everything running as I would expect it or even better an already working solution!
[1] http://jaxenter.com/tutorial-using-jpa-in-an-osgi-environment-36661.html
[2] https://blogs.oracle.com/sivakumart/entry/typesafe_injection_of_dynamic_osgi
[3] http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi
[4] http://team.ops4j.org/wiki//display/paxweb/Pax+Web
[5] https://jira.springsource.org/browse/SLICE
To answer some of your questions, using a single persistence unit but spreading your entities across multiple bundles is not recommended, but may occasionally work. However, if your entities are so closely related that they need to share a persistence unit, splitting them across modules may not make sense. Also, don't forget you can handle compile-time dependencies by separating the implementation and interface for each entity - interface and implementation need not be in the same bundle.
For dependency injection, you may like Blueprint.
Several implementations are available and most application servers with enterprise OSGi support support Blueprint out of the box. It uses XML to add metadata, so classes themselves won't need any modification.

Error preverifying class NetBeans 6.8 using lwuit api

I'm trying to develop a portable J2ME appli, but Netbeans do a class preverification of LWUIT library that uses optional APIs that some configurations don't have, so I get this error when I try to compile on a configuration without JSR-184 (M3G Optional API):
Error preverifying class com.sun.lwuit.animations.Transition3D
VERIFIER ERROR com/sun/lwuit/animations/Transition3D.initTransition()V:
Cannot find class javax/microedition/m3g/Node
I don't want to remove the classes from the LWUIT API because that classes works on other configurations compatibles with JSR-184
What I want is that NetBeans do not preverify the library, It is posible?
Here are some code:
//#ifdef JSR184
//# import com.sun.lwuit.animations.Transition3D;
//#else
import com.sun.lwuit.animations.CommonTransitions;
//#endif
Transition out;
//#ifdef JSR184
//# out = Transition3D.createRotation(500, true);
//#else
out = CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, true, 500);
//#endif
setTransitionOutAnimator(out);
Thanks
We had the similar problems, as I remember BlackBerry handsets are problematic (?) for this JSR-184. What I did to solve this problem, I created different configurations for different targets and removed this problematic classes from LWUIT library, rebuild library for that target, and also modified project settings of related configuration accordingly. Hope it helps.
There is a native blackberry port of LWUIT as well as quite a few tutorials and instructions on how to use it. The native port uses native RIM API's which work far better on the blackberry devices than MIDP API's.
LWUIT's use of 184/226 doesn't bother devices that don't support these profiles other than blackberry which has a broken classloader implementation.
It may be possible, though I havent tried it. Netbeans has two xml files, build.xml and build-impl.xml. Look at these files and look for preverify task, then you can do a bit of testing and ensure that it doesnt preverify the library.
Netbeans ant plugin is a pretty simple setup and you can change it which ever way you want to.

Resources