Can multiple portlets share a singleton? [duplicate] - java

I have a couple of Singleton classes in a Liferay application that hold several configuration parameters and a ServiceLocator with instances to WebServices I need to consume.
I have put these classes in a jar that is declared as a dependency on all my portlets.
The thing is, I have put some logging lines for initialization in theses singleton classes, and when I deploy my portlets I can see these lines multiple times, once for every portlet, since each portlet has its own class context.
For the AppConfig class it might not be such a big deal but my ServiceLocator does actually hold a bunch of references that take a good bit of memory.
Is there any way that I can put these Singleton references in some kind of Shared context in my Liferay Portal?

The problem is that every Portlet runs in its own WAR file and aech war file has its own classloader.
Usually when I had to achieve a requirement like this, I had to put the Singleton classen in a JAR file and this JAR file in the common class loader library instead of packing it into each WAR. (In Tomcat: <tomcatHome>/common/lib or something like that)
Then you'll also have to put all dependent libraries into that common lib dir, too. Don't know how to do that in Liferay, though. For tomcat see this thread: stackoverflow.com/questions/267953/ and this documentation: http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html. Depends on the Servlet container.

Alexander's answer gives the general answer that's true with or without Liferay in mind.
Liferay (as you mention it) adds another option to this: ServiceBuilder. You'll end up with the actual instances contained in exactly one web application, and you'll have an interfacing jar that you can distribute with every dependent application. This way you can more easily update your implementation: It's easy to hot-deploy new and updated web applications to your application server - it's harder to update code that's living on the global classpath.
The global classpath (Alexander's answer) however brings you immediate success while ServiceBuilder comes with its own learning curve and introduces some more dependencies. I don't mind those dependencies, but your mileage might vary. Decide for yourself

With maven portlet you can make a common Spring component and import in the pom of each portlet.
Another solution is to use service builder.
Spring MVC portlet would be the most recommended for this.

Related

How to dynamically load jar files with application context by Spring (with no OSGi)?

I am going to create Java Application that can load external jar files at runtime by FileChooser. I am using Spring Framework, and I want to load jar file and its applicationContext.xml file and inject its dependencies dynamically. I tried to achieve this by OSGi, but it seems very complicated so that I am searching another appropriate variants.
I want to make something like Intellij IDEA plugin installation from the disk.
How can I do this? (After the jar file chosen restarting an application also accepted)
I realy like your approach, unfortunately spring has lifecycles that are strict. As you might know, spring autowires "beans" only. Exactly one lifecycle registers the different bean candidates. After that lifecycle spring (by default) does not accept new classes.
You must use the spring-osgi.
If you only need the CDI part out of spring, you might like to use a different CDI like red hat's jboss server.

is it possible to add jar(with web-fragment.xml) at runtime(means after startup)

I want to add pluggable jar i.e. the jar with web-fragment.xml after server is up-and-running. and perform the scanning of this jar and initialize servlet components defined in web-fragment.xml of newly added jar.
If this is not possible please explain the reason.
Each Java EE application is atomic. It is deployed and undeployed entirely. You can't change application without redeploy. So it is not possible.
Correct solution is differ. You should deploy independent application and provide pluggable interfaces between main application and such plugins. Technical details are depends from situation. E.g. JSF has resource-handler. You can write special class (need be registered in faces-config.xml) for loading JSF pages from nonstandard place.

Is there any native mechanism whereby we can override classes in an existing deployed Struts2 app?

Specifically, if we have an original .war file deployed in a application server, can one deploy a .war which provides different implementations of classes in the original file without having to modify the base code to support this?
Edit. I've formulated the problem wrongly, it's actually simpler I think. We want to expose actions from two distinct WARs in the same base path, rather than a different path for each WAR. Can it be done at the container configuration level?, or do you recommend employing something like URL rewriting?
Not easily. Generally, a deployed WAR becomes a discrete webapp within a Java EE server, and it gets its own classloader. Your second deployment will get another classloader, and although they will definitely share some ancestry, it won't be possible to reimplement things from the other WAR - your second deployment won't be able to 'see' it, because of the way the classloaders are chained together.
It is possible to rewrite running classes using a Java agent, although this is nontrivial. You can transform (rewrite incoming) classes and you should be able to rewrite live (instantiated) classes, although the problem there is that there may be objects on the heap using the old and new code.
Class rewriting is how Eclipse's Hot Code Replace works, and also how JRebel's fast redployment solution functions.
You might be able to use an AOP system like AspectJ if you really want to pursue this - but it sounds like you're trying to solve a build or deploy problem, rather than a problem where AOP would be a more fitting solution.

Spring multiple application contexts vs single application context in an ear

I have inherited an app which is packaged as ear file that has inside
- ear :
-APP-INF/lib (persitence.jar - hibernate+spring ... etc)
-war (web-services)
-jar (mdb)
-jar (mdb)
As I studied the app noticed that each module has inside the jar creates it's own Spring application context that is loaded on runtime.
It works ok but it would not be better to have only one application context ?
I wonder what are the benefits and drawback which this structure compared to the one where it is only an single application context used ?
To be more clear on runtime there are 3 application context roots loaded.It is not only that there are more application context files
Thanks
first of all: are you sure it isn't the same application context everywhere ? have you tested this ?
if they are all seperate:
the advantage is that those application contexts are shielded from eachother, which you could call loose coupling, which is a good thing; one can't influence the other, it keeps things clearer for the programmer.
the disadvantage is, it might be harder to access one application context from the other, but you can always find a way around this.
If the application very large then the application context of different modules is easy to manage and it doesn't create any overhead. At the time when application is up all the context xml files will be combined.
And I will also prefer to maintain separate application context files for separate set of configurations eg. security, datasource, aop etc. should be placed in separate context files.
When the application is small then you can go for single application context file for whole application. Otherwise different application context for different modules is easy to manage in case when you need to do some changes in any one of them. If you combine all of them then it will be very difficult to do any changes in that.
Hope this helps you. Cheers.
Few points against single application-context file that I can think of:
One file will get huge and it will be maintenance nightmare.
Developers of each component will modify,update same file can lead to errors.
Changes in one component will lead to changes in one centralized file, again may lead to issues.
It gives every component developer "Separation of Concern", they don't have to see, know others work while carrying out there task.
I stumbled on this thread which seeking a solution for multi-tenant application. Most articles are just about datasource (Spring HotSwapable datasource targets) etc but what you have is a separate context at the war level.
This gives me another idea of bundling my application in a way that makes it multi-tenant.
If the wars are skinny just to inject special runtimes and provide additional context path qualifies this may work for a large multi-tenant application. Common classes will be loaded at the EAR level and application contexts per war. I guess this should be ok for small number of tenants.

How does a web server/container treat a POJO in respect to other classes like EJB's and Entities?

I'm trying to use plain old java objects(POJO)'s and regular class files where needed and only use EJBs when I need the functionality that they add such as asynchronous calls, pooling, etc. I'm wondering how the server treats this behavior once the project is deployed on a server. Since it is not managed by the container does a new instance have to be created for every stateless session bean pooled that might call one of it's methods? How do things like static methods or state affect this model.
Edit:
1) I can clarify more. The point of Java EE is that you annotate a POJO with #stateless etc so that a container can manage it. You don't have to declare a new instance of a stateless bean you just inject and can make calls to it's type.
2) Most Java EE tutorials and books never mention non annotated classes as a part of your business logic. It's never brought up. This seems strange to me if you can use them in Java EE projects for your business logic and it can get deployed on a server. If you don't need pooling or asynchronous access--the things that a container helps manager through an EJB then you can use theses regular POJO's in your Java EE project.
3) that leads me to my question which is how do I incorporate properly into a project? Do I put them in the EJB project that's connected to an EAR or should they go in the EAR? or Dynamic web project. There is almost no mention or instruction on proper use of regular objects like this. When it gets compiled into a WAR for deployment are there any issues you run into on the server? Isn't it expecting properly annotated EJBs, servlets or JSP?
The don't affect it at all. Classes are classes, objects are objects. They're no managed, they're not interfered with, nothing happens to them. They're not special is any way.
Static singletons are static singletons, Java is java.
All you need to be aware of is the classloader layout of your container, and how it relates to your deployed applications and resources. (Classes in one app can't see classes in another app, for example.) Most of the time it's not really important. Sometimes, it is, as things get more complicated.
But for the most part, it's just Java.
Addenda:
A better way to look at this is to simply group your classes up in to blocks of locality.
Let's take a simple web app that uses EJBs.
The web app is deployed in a WAR artifact, and the EJBs can be deployed separately, as individual EJBs in the container, or, more likely, in an EAR. When you package your application in an EAR, you will likely bundle the WAR within the EAR as well. So, in the end the EAR contains your WAR, and your EJBs.
Now during development, in this case, you're going to have classes that have are in one of three categories.
Classes that are relevant solely to the EJBs (for example the Session Beans).
Classes that are relevant solely to the WARs (such as a Servlet class).
Classes that are relevant to both (a database entity perhaps).
So, a simple way to package them is in three jar files. A jar file for your WAR (in fact, this is the WAR, with the classes in WEB-INF/classes), a jar file for your EJBs, and a jar file for the 3rd type, we'll call that a library.
In terms of build dependency, the WAR build depends on the lib, and the EJB build depends on the lib. But neither the WAR nor EJB depend on each other, as they don't share anything directly, only indirectly through the 3rd library jar. The lib jar is stand alone, since it doesn't have any dependency on either the WAR or EJBs. Note, your EJB Session Bean interface classes will go in to the library jar (since both tiers rely upon them).
In your ear, you simply bundle the lib jar, the WAR, and the EJB jar along with a META-INF dir and an application.xml file. The WAR has its own structure, with the WEB-INF and all, the EJB jar has its META-INF and ejb-jar.xml. But of note is the that lib.jar is NOT in the WEB-INF/lib directory, it's in the EAR bundle and thus shared by both the EJBs and the WAR using class loader chicanery that the container is responsible for.
This is important to note. For example, if you have, say, a simple static Singleton in your lib jar, then BOTH the WAR and EJBs will share that Singleton, since they're all part of the same class loader. To use that Singleton, it's just normal Java. Nothing special there.
If the EJB and WAR were deployed separately, they would EACH need there own copy of the lib.jar, and in the case of the Singleton, they would NOT share it, since each module would have it's own class loader.
So, barring some real burning need otherwise, it's easier to bundle everything in to an EAR and treat both the EJB tier and WAR tier as a single, integrated application.
Addenda 2:
People don't much talk about using classes in Java EE development because there's nothing to talk about, they just use them, like in any Java program. You're over thinking this here.
The 3 jar idiom: war, ejb, lib is one I've used over the years because it separates the 3 concerns, and limits dependencies. Client -> lib -> EJB. It also simplifies the build, since clients typically need just the lib jar and java. In the Netbeans IDE, this is trivial to manage. With minor work, it's straightforward in other IDEs or even in ant/maven. It's not a huge burden, but keeps the 3 parts relatively clean.
Dependency and Jar management is the nightmare of any large Java project, and even more so with EJB when you're dealing with the different deployable artifacts. Anything that can help mitigate that is a win, in my book, and truth is, a clean, stand alone lib jar helps a lot, especially of you need to integrate and use that lib with other code. For example, if you later write an external GUI client using Remote EJBs, or even web services, the lib jar is the only dependency that client has. The benefits of this jar far outweigh the minor pain it takes to set up this kind of library.
In the end the lib jar is just a jar like any other jar you'd want to use in your application (like logging or any other popular 3rd party jars).

Categories

Resources