We are developing a web site with OSGi bundles (Adobe CQ/Apache Sling/Felix and Maven). There are 2 bundles: 1) Webapp 2) Commmon.
The Common bundle contains modules common to Webapp development like encryption, paging, sorting etc.
The bundles are deployed in CQ/OSGi container as follows:
OSGi parent class loader ---|--- Webapp
|--- Commmon
The Common bundle contains some functionalities which maintain configurations (similar to PropertyConfigurator in log4j), connection pool etc as static data.
Now another web site has come up and we want to 1) Re-use Commmon bundle 2) Deploy new web app in same CQ container.
The new deployment layout can be:
OSGi parent class loader ---|--- Webapp
|--- New web app
|--- Commmon
If we use above deployment strategy, the static data in Common bundle is shared between the 2 web apps and creates overlaps (because Common bundle is loaded in 1 class loader which is shared with class loaders of the 2 web apps).
What will be good architecture to re-use Common bundle? Should it be embedded inside Webapp and New web app (so each web app will have its own copy of Common bundle loaded in its class loader)? If yes, which Maven plug-in is suitable for this (I used "maven-bundle-plugin" with "wrap" goal; but the build log has a WARNING message which discourages it's use)?
The best solution would be to remove the statics and continue to use the common lib as a bundle.
If this is not possible then you can use the maven bundle plugin with the webapp bundles. Simply define the common packages you want to embed as private in the maven bundle config of the webapp. These classes will then be embedded.
Related
I have an ear file with a web module and a ejb module(just used for message driven beans). The ejb module has dependency on web module and it's classes. I would need to load the web module first and then ejb module. But the liberty always loading the ejb module first causing com.ibm.ws.container.service.state.StateChangeException: java.lang.NoClassDefFoundError:
How to control the order of modules loading within the same ear file? On traditional webshpere there is an option called 'Starting weight'. Whichever module has lowest value takes precedence and loads it first. so the application works good on tradition Websphere. However, this property seems missing on Liberty. I already looked at this. It only talks about deploying the multiple war files and their order.
If your EJB module depends on Web, that is bad design. It should be the other way around.
If you have such situation , proper way would be to extract shared classes in to a common jar file, let say mycommon.jar and then put that into ear\lib folder. In this way they will be visible by both modules ejb and web.
If your EJB module depends on the javax web api (e.g. servletRequest) that is even worse, and you should redesign such classes to POJO DTOs.
As a last resort you could try what is described here and add <initialize-in-order>true</initialize-in-order> in your application.xml.
FRowe's solution will not work, as classes are not shared between the applications, so changing load order of apps will not help. Each Java™ EE application has its own class loader in a running Liberty server.
Consider using the ability to control app start order as described here: https://www.openliberty.io/blog/2020/06/05/graphql-open-liberty-20006.html?_ga=2.4728563.17466047.1620833568-1423690488.1614284842&cm_mc_uid=99965752544816136653536&cm_mc_sid_50200000=61078141620909829332#ORDER
You'll have to deploy the war module as an app instead of packaging it within the ear, but you should be able to achieve the proper ordering.
I am new to OSGi and am using Equinox "Virgo Tomcat Server" (VTS) along with eclipse blueprint, and got big assignment to do in limited time
There is application already developed in J2EE Style
By using JSP->Struts2->Spring->MySQL and SOAP Web Services.
-There are various layer in the existing architecture
Simple Request flow is as mention below
From UI layer->it goes to strus2 configration-> it goes to Spring Configuration->From Spring configuration xml (that is module wise application context xml) Struts Action class is called -From Struts Action class layer -> it goes to Task layer->handler layer->Service Layer -> Adapter or DAO layer ->DB in some cases from service layer call also goes to WebService layer and communicate with Back-end legacy system
My Queries are as Follows
Q1] From UI/JSP to up-to strtus2 action layer code for every module should be club together in to a single .war file say "onlinebank.war" and from struts2 action onwords module wise code in every layer should go in to Module wise OSGi bundles
For e.g. if there are 10 modules there should be 10 osgi bundles
And each module wise bundle should contain module specific code from every layer after action layer and there should be communication between one war "onlinebank.war" and 10 osgi bundles
Q2]To take Q1 to next level
If there are 10 modules then instead of crunching module specific code in one OSGi bundle,
I have to create 3 bundles for each module(XXXAPI,XXXMain,XXXConfig)
for e.g. TestModule
I] TestModuleAPI (will contain only interfaces and abstract classes)
II] TestModuleMain (will contain implementation of interfaces and abstract classes and will provide some default functionality)
III]TestModuleConfig (will be accessing the default functionality of Main Bundle Via API Bundle and also provide some customize/new functionality)
So if there are 10 Module and 3 OSGi Bundles for each module (API,Main,Config) then for 10 bundles there should be 3*10=30 bundles and there should be proper communication between -single war "onlinebank.war" and the 30 bundles
Also there should be proper communication among 30 bundles it self to resolve the dependencies and works together properly/synchronously
Any help will be greatly appreciated
Regards,
Gokul
This is a big task you are tackling. I did such a migration and am quite familiar with OSGi. Still it took about 2 months. So you should first not underestimate the problems you will be facing.
The next thing is that a typical spring application is not well modularized. As there are no private/public packages in JSE developers tend to ignore module boundaries. The modules often also do not have a clean and small API at all so people known what they should access and what not.
So I think your first task is to refactor the application so each bundle offers a minimal API and other modules only access the API. For this task it might make sense to use an architecture tool that allows to define and control these accesses. While still in spring you create beans from a service interface from the API. Later in OSGi the API will allow to define clean OSGi services. If you skip this step then OSGi will not have big advantages. OSGi only works well if the application is strictly modularized.
Then for the actual OSGi migration I can only urge you to hire some specialist to help you. It will be a waste of time and resources if you do this alone.
It's been a while since I used maven last time for multi module projects. I'm building a webapp, and I'd like to have maven modules:
main module (that aggregates):
a) service - where I keep my logic, usual service layer
b) view - for web interface, talks to service layer only
c) api - for REST Api - talks to the same service layer
I know how to create web.xml and servlet for view module - packaging is set to "war" - and that's something that I deploy on tomcat
But what with api module? Creating new web and servlet files + packaging it as war will create separate application on tomcat (which I don't want to have).
How to approach this issue? What if I'd like to add another module exposed to the end user? What's the best practice.
I have created a multi module maven project as below
- root module(parent module. Building this will build the below children modules)
dao
service
web
dao and service modules creates the jar file. web module creates the final war file to be deployed. service module has the dependency of dao module. web module has the dependency of service module.
Whenever I implement new functionality, I have to modify all the modules from dao to web. I have a maven jetty plugin configured in web module. To test any new implemented functionality in UI I end up building dao and service modules always. Are there anyway to avoid this process and reflect the changes from dao and service modules whenever I run mvn jetty:run in web module?
No, there is no way to da that, and this is the intended behavior.
If you have these 3 projects, this means the have their own lifecycle. If not, the best is to have only one project.
However, you could avoid mentioning a version number in the project, and rely on a parent version number (your root module could also be the parent).
So, you could rebuild everything from the multi-module project.
However, I don't really see the point.
Why do you have 3 projects ?
I have a server side application and want to embed an osgi framework into for dynamic bundle loading.
Suppose I want to expose a QuoteImpl implementing IQuote(instantiated as part of the server container bootstrap/Spring) to be used by different Bundles.
Q1. Is there a clean way of exposing server-application instances to Bundles ? (btw because of legacy it is not possible to make server code into bundle :) and donot want to make entire application osgi'ed.
Tried exposing via a service and bundle to cast into an IQuote. Not sure I am doing it well but fails with unresolved compilation problems as IQuote resides in the core app projects as opposed to the bundle project. any ideas?
Yes the way to do this is with a service. The "host" application would publish the service and the bundles inside OSGi would consume the service in the normal way.
The key to get this working is that the service API (i.e. the package containing IQuote) must be exported by the host application through the system bundle exports. You can control this by setting the org.osgi.framework.system.packages.extra property when you create the embedded OSGi framework. I wrote a blog post on this subject that should help you get started (look for the heading "Exposing Application Packages").
You state that you have compilation problems. To fix those it's necessary to know how you have structured your projects and build system.
This is how I embedded Equinox OSGi runtime in my Java class. I suppose you could do the same. https://github.com/sarxos/equinox-launcher/blob/master/src/main/java/com/github/sarxos/equinox/Launcher.java