share common data in wars under ear - maven

To reduce database hits, I've used static variables to store data from database.
At time of WAR deployment this data is stored in these variabes as it is not changing so frequently.
This scenario was working fine as the scope was with only single a WAR. Now I have another application where I need access to these varibles
But due to different application scope,I'm unable to access them in another application.
Also I'm having an EAR which encloses both above WAR and one JAR containing some common buisness logic of both WARs.
So under EAR is it possible to share these variables via JAR or using some different approach?
If any javaEE concept can help in this scenario, then please let me know about it also.
I'm using maven with Jboss7.1.1.Final for this

You should use Infinispan, the built-in caching mechanism of JBoss 7 https://docs.jboss.org/author/display/ISPN/Getting+Started+Guide+-+JBoss+AS+7. Caching data in static fields is generally frowned upon in Java EE.
However should you still want to cache your data in static fields you need to make sure the class with the cache was to be shared across all WARs. This means you have to create skinny WARs.

Looks like you need an Enterprise Caching Solutions. There are lots of choices on the market. They include but not limit to
Open Source framework
Memcached
EHCache
Infinispan (mentioned by Phillipe)
Commercial product
Oracle Coherence
GigaSpaces XAP
GemFire
For your second question, as long as your JAR is deployed in the EAR/lib folder, you should be fine.

Related

How to control module loading order in Liberty profile

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.

Sharing files and backbeans between different wars Java EE

I am working on a large scale system using PrimeFaces 5.0, Java EE 7, Maven 3.0.5, Netbeans 7.4 & GlassFish 4.0
I want to implement it as (multiple WARs , multiple EJBs , one EAR).
Multiple wars could have common files like (JS, CSS, XHTML, Backbeans & Converters)
i have achieved this using jar which contains this resources.
different WAR files, shared resources
I need a session-scoped bean to be shared between different wars, I found this but i found it more than what i need.
http://docs.oracle.com/cd/E18686_01/coh.37/e18690/glassfish.htm#CEGBDHJB
so my questions is:
Is using a jar is the right approach to share what i want ??
where do i put jars like primefaces or omnifaces in the project where they use the same class loader ??
How can i share session-scoped between different wars ??
I have been working on a ear project with similar requirements as yours, according to our experience :
Sure. We have seperated our war projects and use them as extended controllers to carry out front end logic and passing data to view, and they make their service calls via a jar file called common-services.jar . Our whole service layer is living on a single jar file. However if you ask my personal opinion, I think it would have made a lot sense to create a third war file just for the services, and talk restful with all the front-end repos. That way service calls could be opened to third party users without any further work. So to sum it all up, yes it is an acceptable approach, but you should also consider packing it as war.
On a parent pom above all war, so all war files use the same version and it is managed from a single pom.
Carry all session based operations to your third jar / war we have discussed in question 1. Makes much more sense that way. Or I suppose you will need solutions like single sign on. But my first suggestion works like a charm for us.

WebSphere7 classloading Issues

I am just wondering, if the below is possible with Websphere or not?
I have an Enterprise application using Websphere 7 and with PARENT_LAST classloading mode. I am now trying to use a third party feature namely, gemfire in the application. My application with gemfire runs perfectly in PARENT_FIRST classloading mode. But, I can see some linkage errors occuring because of PARENT_LAST setting. Temperarly, I could solve them by removing the classes that are conflicting from gemfire jar(By this, I am actually asking those removed classes to be loaded from web app server). But, I am not sure if this will create some bigger issues as my appliaction grow to its fullest.
My question is : Suppose we have abc.jar in both web app server and also in gemfire.jar, with PARENT_LAST loading mode.Is it possible to solve the above class conflicts by not removing any class files from jars, instead tell the classloading mechanism to use the class loaded from web app server at a particular case and use the same class loaded from gemfire jar(meaning load from application) at another case?
Thanks
Yes, it is possible. We are using a similar setup. You should be very careful though and only use the exact same jars (or at least the same classes) in all the places you need to have them.

JBoss Deployment Info

More of a standard practice questions:
Is there any difference in deploying an app as EAR vs WAR? How do you decide? (I know WAR is just a web application may or may not have Java EE features like messaging)
Lets say I have a Spring MVC application stack with Hibernate (MySQL DB), should this be deployed as a War or EAR?
When do we need to worry about JBoss deployment descriptors, if I am not using EJBs. (Just Spring MVC). Lets assume I have JMS as well. Do we need to configure/update/create any other JBoss related config files?
When we package our application EAR/WAR, it include EVERYTHING that we need for our app. Is there a scenario where we need to keep some config / xml files outside of this archive in a specified JBoss folder?
Is it common practice to deploy directly from Eclipse or better to use Ant, etc? Advantage / Disadvantage?
Obviously, I am a newbie :-). Trying to understand this.
1.
This is not always an easy decision, but for beginners and for small projects I would say it's nearly always a WAR. The reason for using an EAR is mainly to isolate a business layer from a UI/Web layer. See this question for more details: How can one isolate logical layers of an Java EE application
2.
I might be mistaken but I think that Spring people typically prefer WARs.
3.
JBoss (vendor) specific deployment descriptors are mostly needed to configure so-called "administered objects" and security. Sometimes they can be used for extra features that are not covered by the Java EE specification (e.g. setting the web root for a WAR). Administered objects are typically data sources (connection to a database) and JMS destinations (queues and topics).
In the traditional Java EE approach these have to be created as far away from the code as possible, which typically means a system admin would create them inside the target AS using some kind of GUI or admin console. In this setup, you as developer would throw a WAR with "unresolved dependencies" over the wall, and a system admin (or "deployer") would then spend days figuring out what those unresolved dependencies should be.
If the communication is relatively good between developers and deployers, the WAR or EAR might be thrown over the wall together with a readme-file, that at least gives some insight into which resources are needed. Depending on the organization the development team might not get any access or feedback about how those "unresolved dependencies" have been resolved. E.g. a data source with a max of 5 connections may have been created, but this may be insufficient if some code does say 10 parallel queries. Without the development team knowing the exact data source configuration, some classes of runtime problems and performance issues may be relatively hard to solve.
To mitigate these problems, some vendors, for some artifacts, offer the developer to create those "unresolved dependencies" instead using proprietary deployment descriptors which are then embedded in the WAR or EAR. For simple local JMS destinations this is then in most cases the end of it, but for data sources there is a little bit more to it. Namely, there has to be a mechanism to switch between data sources for different stages such as Dev, Beta, QA, Production etc. Additionally, it's rarely a good idea to have production passwords in the source code.
If you have a simple app that you want to try out locally, stages and production passwords are not a concern. If you deploy for a (large) company it is.
In Java EE 6 you can define a data source using a standard descriptor (web.xml, ejb-jar.xml or application.xml), and in Java EE 7 you can do the same for JMS destinations. There is no standard way to configure those based on stage, but there is a glimmer of hope that Java EE 8 will address this (see e.g. JAVAEE_SPEC-19). Vendors are not universally happy with those standardized methods, and their main documentation will almost always extensibly tell you how to do those things using their proprietary tools and descriptors, and if you're lucky as a small note tell you there's a standardized way (and then sometimes downplay that or scare you by saying it's not recommended to be used in production).
4.
See answer to 3 mostly. One option to solve the problem of how to switch between stages and keep production passwords out of the WAR/EAR, is to have the full definition of said data source inside the AS (inside JBoss in your case). Every AS installation is tied to a specific server in this setup. If data sources need to be updated, removed or new ones added, you have to communicate with your operations team (if any). As said, depending on your organization this can be anything between trivial and practically impossible.
5.
When developing you most often use your IDE to do a deployment. For production you would never do that. For production you may build with Ant (or Maven) and deploy via something like Jenkins, or e.g Chef.
Check here : .war vs .ear file
If you read the preceeding response, you'd guess that "WAR" it is.
Deployment descriptor are needed to manage the modules of JBoss, if you don't have any conflict or don't need any tweaking, you won't need any deployment descriptor.
You may need to play with some JBoss file if you want to add modules to JBoss, or configure datasources, etc. Read the JBoss documentation for more info.
You can deploy from eclipse during your development phase, but as your other environments (qualification, production, test, etc) should be separeted from your developing one and that they won't have any eclipse installed on them, you should get used to manage your server from the command line and drop your war's in the right directories.
It's a short answer, but I hope it will help.
Read JBoss documentation for more info.

How do you share Java Caching System (JCS) resource across multiple EJB

I am using JCS to store the ldap search results which should be shared by multiple EJB. I have created a singleton class to initialize JCS only once but due to EJB's classloader, it's been initialized multiple times with its own copy. so search resources are not shared.
How are you guys resolving issue where you need to share the cache across multiple beans?
I am looking for cache within JVM. (Not the remote e.g memcached etc.).
Glassfish is used as an application server.
I haven't been able to test it yet, but I think that one of the techniques explained in the "Circumventing Class Loader Isolation" chapter of the Application Development Guide for the version of Glassfish you are using may solve you problem.
Short version, at least valid for versions 2-3-4 : use the Common Classloader (what exactly this common classloader does and its relation to the other classloaders is explained in the same manual). There are several ways to do this:
copy the jar to domain-dir/lib
or copy the jar to as-install/lib
or run asadmin add-library --type common /path/to/your.jar (will only work in version 4 iirc)
There are several questions here on SO that are related to "Circumventing Class Loader Isolation" (just use that search term), look there for examples and more discussion.
Simply put, the singleton will likely "live" where your caching implementation class lives, as that's the classloader in the hierarchy that "owns" the class.
So, if each EJB is separately deployed, with their own copy of the cache lib jar, they'll each get their own copy.
If your beans are deployed in a composite EAR, sharing a single instance of the lib jar, then that cache will be shared across the beans in the EAR.
If you remove the lib from the deployment completely, and put it outside the container ($DOMAIN/lib/ext for example), then that cache will be shared by EVERYTHING in the domain (EJBs, EARs, WARs, etc.).

Resources