NBP rich client in a multi-tier enterprise application? - java

Just started a project that involves a rich client implemented in Netbeans Platform (NBP), Spring framework is chosen to implement business logic and for data access. Since I've come from a web application development background, I have some questions and would also like some suggestions.
What are the options for a rich client to integrate with Spring?
Any best practices/books/docs regarding a rich client in a multi-tier Java EE environment?
Anything that needs special attention?

We recently went through a similar experience at the company I work for. Sadly, we couldn't find any sort of definitive guide for the process. What we found were partial guides here and there. I'm not certain how others have dealt with this issue, and I am eager to see if any other solutions are posted here. I can, however, tell you how we handled it and hope that you can learn from our experience.
From the onset, we knew that we wanted to be able to control what version of Spring (and, in our case, Hibernate) we would use. Naturally, the versions built into the NetBeans IDE are a bit dated and we wanted to have the cutting-edge available when developing our server code.
What we ended up doing was creating two separate projects: one for our server code (our Services, DAOs, and Domain entities) and one for our client application. We then jared up the server code, copied the jar and its dependencies to the client project, and listed those jars as dependencies in the client code. We created a module in our NetBeans project called SpringHibernate, which housed those jars, and which almost every other module depended on.
I would recommend creating an ant task that will strip out the version numbers of your jars before adding them to your NetBeans project. This allows you to seamlessly update your jars in the server code without the client code ever knowing the difference. (NetBeans can be kind of picky when you start removing and re-adding jars.)
The first major task then is to create a Util class that can load your applicationContext.xml and return beans from the context. That process is outlined here.
One of the major snags that we hit was the creation of Sessions (or EntityManagers in JPA terms). The NetBeans Platform is a highly threaded environment, and EntityManagers are designed to only work on a single thread. To get around this we went with the Open Session In View route*. We created a class that could load the same EntityManager into any thread that requested it. We then created client proxies of our services which would load the EntityManager into its thread before calling the actual Spring-managed service. The added bonus of creating client proxy services was that they were able to be found with Lookup.getDefault().lookup(Service.class) via the #ServiceProvider annotation.
You then should create a custom LifeCycleManager that can teardown and close your EntityManager and EntityManagerFactory on application shutdown.
I hope this helps!
*I know that Open Session in View has been labeled as an AntiPattern, but as long as you understand the problems associated with it you can mitigate those issues (by caching things objects that are unlikely to change over time, making smart database calls, etc.). Plus, I remember during our research we found a forum post by Gavin King stating that Open Session In View is the recommended route for client applications. Of course, I can't find the post now, but it's out there somewhere.

Related

OSGi: how to securely share connection between bundles

I am trying to develop a java software based on OSGi (Apache Felix), which different module (which may contain more than one jar file) could be developed by different developers from different companies.
the question is: i am wondering how should i provide database connection to these modules. if i share the same user credential between modules, they may accidentally or intentionally use each other tables or data which should be avoid because of information privacy. or if i force each module to have its own connection with its own user credential then there will be many connections.
note: i am using mariadb as backend.
i know this problem is not a OSGi specific problem. i am wondering if anyone has faced such problem and has proven solution for this scenario (i only describe my development environment).
any idea,
thanks
First of all, your issue of multi-tenancy isn't something any system (beeing it OSGi or not) is made for. Therefore you need to take care of this yourself. Most OSGi applications still use datasources if you want to connect to a db, via JPA for example. Usually those datasources are registered as OSGi services.
Coming back to your multi-tenancy issue, you should make sure for each you have another datasource and just use that datasource in your application. For example make sure each tenant has it's own configuration and therefore receives his own Datasource as configured in your configuration. This way you can make sure each tenant is separate to each other.
OSGi cannot achieve the level of security you need for this scenario. An OSGi Framework is intended to represent a single logical application. If bundles exist in the same JVM and OSGi Framework, then it is very hard to prevent data leaks, especially against determined attacker.
You need to isolate processes at the very least, and run those processes as separate user IDs.

Load only required services spring framework

I'm looking for a way to create a free version and a paid version of an application. I was wondering if spring has the functionality to group/tag services so I can switch between services i.e. services which don't do much for a free user and the actual service for the paid user.
Is this the right approach? or is there another framework which lets me do this and works well with spring?
Is there a way I can do the same in the front end i.e. show or hide features/icons based on the type of user?
-- Edited --
The project is a multi module maven project with a war module and 3 jars which uses Spring framework with spring security (nothing fancy) and angularjs.
The requirement is that I should be able to build the war file based on different configuration. For example, lets say a client doesn't want a particular feature, I should be able to turn it off by just changing some configuration. So the user will not see that particular feature anymore.
Can it be done?
My advice is to do the licensing in your code. Its much
more flexible, and its not difficult to implement! and easier to maintain....
You can use bean definition profiles to use different bean implementations depending on startup parameters, but that would require that you are in charge of the startup parameters used for launching the application (i.e. this would not be a suitable solution for an application that is downloaded and run by the customer on his own machine; then the startup profile settings could be hacked).
More information on the intended application architecture is probably needed to give good advice here.

Share object between JavaEE applications on the same JVM (using JNDI)

I'm running a JBoss AS 7.1.3.Final installation with a lot of applications. One of those applications provides common resources and functionallities used by all applications (let's call it framework). I'm also planning to move to WildFly 8, if this is an useful information for your answer.
All applications should only be accessible, if the framework is available (up and running). My current implementation to achive this dependency is not that nice** and as I'm currently re-designing some parts of the environment, I'm looking for a much neater solution for it. My first idea was to create some kind of a manager which will be instantiated by the application server and is available to all applications. So after an application is started, it could register itself on the manager and as soon as the framework is up, the applications will be notified.
Is this possible using the JNDI of the JVM where all applications + framework are running? How must this be implemented? It's really hard to find useful information about how the JNDI works and what is possible with it. Do you have any other, simplier ideas, how to share a class instance between applications?
Thank you.
** Currently I'm using a EJB-timer in the applications and a singleton EJB in the framework. The framework is available as soon as the EJB lookup succeeds.
--
Edit #1
Some more informations as requested by Nikos Paraskevopoulos
One functionionality that is provided by the framework is the maintenance mode. The applications will check, right after startup, if it is blocked for normal users. It will also receive notifications about planned maintenances. (central DB, the application has no rights on it)
Common stylesheets or layouts are deployed with the framework.
The user informations are provided by the framework. (central DB, the application has no rights on it)
The main problem is: How could I avoid any timers? I have no idea, how I could ensure, that the framework is up before everything else.
A few thoughts:
JBoss has the capability of ordering deployments according to their dependencies. See here and here. So, if all the "applications" depend explicitly on the "framework", your problem may be solved.
It seems you have a quite strongly coupled configuration. Would it be possible to decouple them, e.g. provide the service through web services (SOAP/REST)? Of course this introduces extra overhead for the communication and the refactoring...
JNDI can be seen (very roughly) as a name to object map shared across the applications. As such, you may share stuff through it. But I do not see how will you solve the timing problem, i.e. wait for a service to be available before using it from the "applications". The manager component you mention can be placed in JNDI.
This is not a complete answer, but it would not fit as a comment either. Maybe if you presented more details on the nature of the applications, the frameworks used etc, you could get more specific answers.
Good luck anyway
Edit #1:
Maintenance mode: This may be nice for using with JNDI. A servlet filter that intercepts every (applicable) request will check a global JNDI name; if it is not found (i.e. framework not started) or it is false, it will short-circuit the processing of the request, sending back the "maintenance mode" page. The framework will have to set a Boolean in the global JNDI name as soon as it has started and maintain its value, i.e. set it to false if maintenance mode is active.
Common stylesheets: This is really covered by the maintenance mode flag, I believe. Layouts: It depends on the view technology/layouts technology.
User information: This is a good candidate for SOAP/REST implementation. It is not expected to be called frequently, so I assume overhead will not matter.
I think OSGi is the technology you should consider. Basically you have an OSGi container with applications (called bundles) which provide or consume services. So you would have a framework service which is consumed by all applications. JBoss is an OSGi container, as far as I know.

Programmatically controlling application servers

I'm creating an application that relies heavily on dynamic creation/management of various resources like jms queues, webservice endpoints, jdbc connections... I have a background in java EE and am currently working on a jboss 7 server however I'm finding it increasingly difficult to control these things programmatically. The hardest thing to control seem to be the webservices. I need to be able to generate WSDLs (and XSDs) on the fly, manage the endpoints, soap handlers etc and the system simply does not seem to be set up to do that.
Other application servers don't seem to really offer any groundbreaking solutions so I'm wondering whether perhaps java EE is not the best solution to this particular problem?
Is there an application server that allows you to do just that? Is there another technology that does? Should I just roll a custom solution that integrates all the separate modules (e.g. a jms server, a web server etc...)?
UPDATE
To clarify, most java EE stuff is accomplished through a mixture of annotations and XML configuration. This however assumes that you have a POJO and/or a jar/war/... per resource.
Suppose I have a #WebServiceProvider bean which can be reused for multiple input/output combinations (for example because it dynamically redirects the content). I need to be able to deploy a new "instance" of the provider on the fly. This means I do not want to duplicate the code and redeploy it, I just want to take that one existing bean on the classpath and deploy it multiple times with different configuration settings. This also means I need to manage the WSDL dynamically. The end result should be a webservice that works pretty much like a standard webservice on the application server with the necessary integrated security, soap handlers,...
I imagine that at some point in the application server code, there must be a class "WebserviceManager" which has a method like "createWebservice(...)" that is actually used by the deployment module whenever it discovers a webservice annotation. I want access to that method and similar methods for creating jdbc connections, jms queues,...
You can use OSGi for these kind of scenarios. It is perfect for hot deployment of varios modules.

What's the best way to share business object instances between Java web apps using JBoss and Spring?

We currently have a web application loading a Spring application context which instantiates a stack of business objects, DAO objects and Hibernate. We would like to share this stack with another web application, to avoid having multiple instances of the same objects.
We have looked into several approaches; exposing the objects using JMX or JNDI, or using EJB3.
The different approaches all have their issues, and we are looking for a lightweight method.
Any suggestions on how to solve this?
Edit: I have received comments requesting me to elaborate a bit, so here goes:
The main problem we want to solve is that we want to have only one instance of Hibernate. This is due to problems with invalidation of Hibernate's 2nd level cache when running several client applications working with the same datasource. Also, the business/DAO/Hibernate stack is growing rather large, so not duplicating it just makes more sense.
First, we tried to look at how the business layer alone could be exposed to other web apps, and Spring offers JMX wrapping at the price of a tiny amount of XML. However, we were unable to bind the JMX entities to the JNDI tree, so we couldn't lookup the objects from the web apps.
Then we tried binding the business layer directly to JNDI. Although Spring didn't offer any method for this, using JNDITemplate to bind them was also trivial. But this led to several new problems: 1) Security manager denies access to RMI classloader, so the client failed once we tried to invoke methods on the JNDI resource. 2) Once the security issues were resolved, JBoss threw IllegalArgumentException: object is not an instance of declaring class. A bit of reading reveals that we need stub implementations for the JNDI resources, but this seems like a lot of hassle (perhaps Spring can help us?)
We haven't looked too much into EJB yet, but after the first two tries I'm wondering if what we're trying to achieve is at all possible.
To sum up what we're trying to achieve: One JBoss instance, several web apps utilizing one stack of business objects on top of DAO layer and Hibernate.
Best regards,
Nils
Are the web applications deployed on the same server?
I can't speak for Spring, but it is straightforward to move your business logic in to the EJB tier using Session Beans.
The application organization is straight forward. The Logic goes in to Session Beans, and these Session Beans are bundled within a single jar as an Java EE artifact with a ejb-jar.xml file (in EJB3, this will likely be practically empty).
Then bundle you Entity classes in to a seperate jar file.
Next, you will build each web app in to their own WAR file.
Finally, all of the jars and the wars are bundled in to a Java EE EAR, with the associated application.xml file (again, this will likely be quite minimal, simply enumerating the jars in the EAR).
This EAR is deployed wholesale to the app server.
Each WAR is effectively independent -- their own sessions, there own context paths, etc. But they share the common EJB back end, so you have only a single 2nd level cache.
You also use local references and calling semantic to talk to the EJBs since they're in the same server. No need for remote calls here.
I think this solves quite well the issue you're having, and its is quite straightforward in Java EE 5 with EJB 3.
Also, you can still use Spring for much of your work, as I understand, but I'm not a Spring person so I can not speak to the details.
What about spring parentContext?
Check out this article:
http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html
Terracotta might be a good fit here (disclosure: I am a developer for Terracotta). Terracotta transparently clusters Java objects at the JVM level, and integrates with both Spring and Hibernate. It is free and open source.
As you said, the problem of more than one client web app using an L2 cache is keeping those caches in synch. With Terracotta you can cluster a single Hibernate L2 cache. Each client node works with it's copy of that clustered cache, and Terracotta keeps it in synch. This link explains more.
As for your business objects, you can use Terracotta's Spring integration to cluster your beans - each web app can share clustered bean instances, and Terracotta keeps the clustered state in synch transparently.
Actually, if you want a lightweight solution and don't need transactions or clustering just use Spring support for RMI. It allows to expose Spring beans remotely using simple annotations in the latest versions. See http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.
You should take a look at the Terracotta Reference Web Application - Examinator. It has most of the components you are looking for - it's got Hibernate, JPA, and Spring with a MySQL backend.
It's been pre-tuned to scale up to 16 nodes, 20k concurrent users.
Check it out here: http://reference.terracotta.org/examinator
Thank you for your answers so far. We're still not quite there, but we have tried a few things now and see things more clearly. Here's a short update:
The solution which appears to be the most viable is EJB. However, this will require some amount of changes in our code, so we're not going to fully implement that solution right now. I'm almost surprised that we haven't been able to find some Spring feature to help us out here.
We have also tried the JNDI route, which ends with the need for stubs for all shared interfaces. This feels like a lot of hassle, considering that everything is on the same server anyway.
Yesterday, we had a small break through with JMX. Although JMX is definately not meant for this kind of use, we have proven that it can be done - with no code changes and a minimal amount of XML (a big Thank You to Spring for MBeanExporter and MBeanProxyFactoryBean). The major drawbacks to this method are performance and the fact that our domain classes must be shared through JBoss' server/lib folder. I.e., we have to remove some dependencies from our WARs and move them to server/lib, else we get ClassCastException when the business layer returns objects from our own domain model. I fully understand why this happens, but it is not ideal for what we're trying to achieve.
I thought it was time for a little update, because what appears to be the best solution will take some time to implement. I'll post our findings here once we've done that job.
Spring does have an integration point that might be of interest to you: EJB 3 injection nterceptor. This enables you to access spring beans from EJBs.
I'm not really sure what you are trying to solve; at the end of the day each jvm will either have replicated instances of the objects, or stubs representing objects existing on another (logical) server.
You could, setup a third 'business logic' server that has a remote api which your two web apps could call. The typical solution is to use EJB, but I think spring has remoting options built into its stack.
The other option is to use some form of shared cache architecture... which will synchronize object changes between the servers, but you still have two sets of instances.
Take a look at JBossCache. It allows you to easily share/replicate maps of data between mulitple JVM instances (same box or different). It is easy to use and has lots of wire level protocol options (TCP, UDP Multicast, etc.).

Categories

Resources