I have a Java/Spring/Hibernate application with a payment module. Payment module has some domain classes for payment subscription and transactions etc. Corresponding hibernate mapping files are there. This module uses applicationContext.xml for some of the configuration it needs.
Also, This module has a PaymentService which uses a paymentDAO to do all database related work.
Now, I want to use this module as it is(without any or minimal re-writing) in my other application(Grails application). I want to bring in the payment module as a jar or copy the source files to src/java folder in Grails.
With that background, I have following queries:
Will the existing applicationContext.xml for Spring configuration in the module will work as it is in Grails? Does it merge with rest of Grails's Spring config?
Where do I put the applicationContext.xml? classpath? src/java should work?
Can I bundle the applicationContext.xml in Jar(If I use jar option) and can overwrite in Grails if anything needs to be changed? Multiple bean definition problems in that case?
PaymentService recognized as regular service? Will it be auto-injected in controllers and/or other services?
Will PaymentDAO use the datasource configuration of Grails?
Where do I put the hbm files of this module?
Can I bundle the hbm files in Jar(If I use jar option) and can overwrite in Grails if anything needs to be changed? Which hbms are picked? or, there will be problems with that?
Too many questions! :)
All these concerns are actually before trying. I am going to try this in next few days(busy currently). Any help is appreciated.
Thanks.
There are a couple of things you'll want to consider:
You'll need to package your applicationContext.xml to avoid namespace clashes - that is, you'll probably put it in src/resources/com/company/module/applicationContext.xml
This application context really needs to be compatible with the grails application - it'll need to access the DB connection used by your app - make sure it doesn't define its own - See section 14 of the docs - http://grails.org/doc/latest/guide/14.%20Grails%20and%20Spring.html
Section 15 of the docs - http://grails.org/doc/latest/guide/15.%20Grails%20and%20Hibernate.html describes using hibernate mapping files
15.4 points out some good articles - http://jasonrudolph.com/blog/2006/06/20/hoisting-grails-to-your-legacy-db/ and http://www.infoq.com/articles/grails-ejb-tutorial
Probably not the exact answer you were looking for, but I hope this helps.
Related
I want to shared common application context in a multi-war Spring application, so i don't need to defined beans again and again. But i don't want to instantiate those beans defined in this common application context in each webapp. I only want to instantiate those beans once and share by all the webapps. Is it possible? Bare me if i'm wrong.
PS: this common application context exists in jar, which i'll import to every webapps.
1, Below article tell us how to share the common application context, but need to instantiate those beans in each webapp.
How to import spring-config.xml of one project into spring-config.xml of another project?
2, Below is another article i just read, i demo it, but still don't get what i want, beans got instantiated twice. Can someone check this section "Why would you want to use this?" in the article, i don't get it, do they have a solution there, can someone help me here, thanks a lot for your time.
http://spring.io/blog/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/
here is the demo source code in second article: https://github.com/jasonluo/ceciic/tree/master/Research/multiple-contexts-sample
Updates
The problem of case2 is because i didn't deploy as a ear file, thanks Deinum for pointing this out, i'm using tomcat, so there is no way to achieve that.
Our solution now is using REST to access the service webapp which running in a separate server.
Don't, there is usually classloader isolation going on to prevent this. Doing this right usually requires a thorough understanding of classloading, Java EE, packaging and your server.
Having that said there is way to do this as outlined in the blog you posted. You have to:
package both WARs into an EAR (this means you have to use and appserver like WildFly AS and can't just use a servlet engine like Tomcat or Jetty)
package both WARs as "skinny" WARs with at least Spring (and all its dependencies) and the shared beans (and all their dependencies) in the lib/ folder of the EAR instead of the WEB-INF/lib folder of the WARs.
Even then it depends on implementation details of the server. AFAIK it is not guaranteed to work under the Java EE specification. For example it likely won't work in GlassFish.
Update
I can't tell if the output of your demo is correct because I couldn't find a build file.
Yes, Tomcat does not support EARs, you could use Apache TomEE which is very similar and supports EARs (I don't know if TomEE does classloading in a way that makes this work). In theory you could also make use of the common classloader in Tomcat but that would be quite a hack.
There is a way to do it, using Spring Dynamic Modules, but it requires OSGi environment, which is quite different from simple Tomcat. Few articles worth reading:
Deploying Spring MVC applications to OSGi
Hello world style example
Blueprint - a further development on DM
Another blueprint documentation reference to Spring
That being said there is not a lot of up to date information about Spring with OSGi, but it's worth a try to achieve just what you said (but of course, with additional performance cost)
I'm trying to design the architecture of a medium-sized web application in Java and I would like to get some advice on how to do it.
The project consists on a base website plus a number of modules. For instance, one module would provide user registration, another module would offer a web service, and so on...
Whenever I need to deliver the application to a new customer, the ideal thing would be to pick up the modules he wants, do some theming (css, images, maybe jsp) and developing the custom modules he may need, if any.
I've taken a look to maven multi module projects, war overlays, but I find it difficult to partition the application, especially in regard to the modules' configuration (for example, merging a global spring configuration from the modules). Can somebody point me to an example of such a system? Thanks in advance!
merging spring configuration is easy. In each module, package up a spring context file in it's /WEB-INF/classes directory. When you overlay, all classes and resources in WEB-INF classes in the dependency will be put into WEB-INF/classes in your app. (ps, this also works if you package as .jar instead, but you won't be able to overlay .jsp files if you do)
Then it's just a matter of importing them. This is best done by using a set pattern to find the files. Here's an example:
<import resource="classpath*:/module/*-context.xml" />
This will import all the classpath resources that match this pattern.
Annotation based example:
#Configuration
#ImportResource(value={"classpath*:/module/*-context.xml"})
public class MyConfiguration { ... }
It's the web.xml configuration that will cause you more trouble than anything if you have the need to do any web.xml customizations in modules. You could use servlet 3.0 for this of course, but it requires the right server to deploy on.
fwiw, after some experience with plain Spring import we developed tiny framework for osgi-less modularity for Spring. The first problem with import is the bean name clashes you can not have same-named singleton in two contexts, and many other hassles.. tbc https://github.com/griddynamics/banshun
--
Mike
I am having some problems getting Hibernate and Spring up and running. I have a web server project which makes use of several other projects which have persistent entities in them. The problem I have is that I get a ClassNotFoundException for an entity class that is stored within another jar inside of WEB-INF/libs.
Do I need to have a persistence.xml for each jar that contains entity classes?
Please let me know if you need to see any configuration files.
Depending on your set up there are probably a number of different ways to solve this - and none them usually feel idea (IMO).
The essential problem is to do with ClassLoader isolation. There are rules as to what the files within a jar can access.
In your particular case, the easiest way to solve it is probably to put the persistence.xml within the parent web project. If you are not using persistence xml, you need to bootstrap hibernate/spring from the web project.
The parent web project should have access to all the libraries within its WEB-INF/lib whereas each of the jars in the libs folder may not have access to each other.
You could set up another persistence.xml in each jar but they would not be composited together into one persistence unit. You would need to use a different pu depending on which entity you wanted.
I'm creating a Java web application, making use of CDI. My War includes various Jar files that are bean sources (including the META-INF/beans.xml file). My beans are automatically discovered when running inside a Java EE container like JBoss (I'm currently using JBoss AS 7.1.1). This much is working well.
I want to be able to extend the web application, ideally by allowing it to load classes from Jar files stored in a configurable location (so at a location specified by a system property). This too is fine, since I can use a ClassLoader to resolve classes and resources. What I'm missing is the ability to have CDI scan these external Jar files and include their beans.
This would allow my application to host plug-in functionality including new REST resources. I don't mind if I had to restart the application for it to pick up classes and resources contained within these external Jar files.
I can see no way of achieving this. Is this even something that should be attempted in this kind of environment?
I can see no way of achieving this.
You actually have two options:
Use the CDI extension mechanism to work with beans / bean-archives
at startup time and to modify them in the way you want. Have a look at the examples provided in the documentation, this should give you a start.
Work with the BeanManager at execution time. Have a look at this similar question.
I have classes that are named exactly the same across different plug-ins that I use for my application, and I'd like to be able to configure them properly with Hibernate. The problem is that it looks like Hibernate dynamically generates a class' package name when trying to find a class when it's doing its mapping. With one plug-in this scheme works, but across multiple plug-ins it's not working. It looks like Hibernate gets confused when dealing with Hibernate configuration files across multiple plug-ins.
Is this because each plug-in has its own class-loader? What is the best way to proceed to make this work with the existing plug-ins and Hibernate?
The problem is, that every plugin has its own Classloader and Hibernate uses Reflection to find the right classes.
I have a very nice article at home about exactly this problem, but this one is in German. I will try to explain what you need to do.
In order to have the datastructure shared over several plugins, you have to put it in a plugin and enable a feature called buddy-policy.
Lets say you have a main-application-plugin which is initiating hibernate on startup, this plugin needs to "see" the classes from the datastructure-plugin. To do this the main-plugin sets its Buddy-Policy to "registered" and the datastructure-plugin registers itself as a "buddy". Unfortunately you have to do this all directly in the manifest file, at least in 3.3 there was no way to do this in the editor.
Once this buddy-policy works, Hibernate will also.
I looked up my old application and here is how I did it.
The main-application (toolseye.rcp) is dependent on the hibernate plugin (de.eye4eye.hibernate) and the datastructure-plugin (toolseye.datastructures)
The hibernate-plugin specifies its buddy-policy as "registered"
The datastructure-plugin registers itself to the hibernate-plugin
Here are the important lines:
Hibernate-plugin de.eye4eye.hibernate
Eclipse-BuddyPolicy: registered
Datastructure-plugin toolseye.datastructures
Eclipse-RegisterBuddy: de.eye4eye.hibernate
Put those line directly in the MANIFEST.MF
Both plugins need to reexport their packages in order that the main application or whatever layer you have in between can use them.
Hope that helped.
Just to make this complete.
Instead of using Hibernate, EclipseLink could be used as JPA-provider in a Eclipse RCP application. EclipseLink is the former TopLink from Oracle and has been choosen to be the reference implementation for JPA 2.
The point for an RCP is, that EclipseLink is available as OSGI-Bundles (org.eclipse.persistence.jpa), and due to that it can load classes from another plugin without an additional buddy-policy.
Currently I was playing around, using the following project structure (Model-View-Presenter Pattern). The names in the brackets specify the dependecy plugins (not all are included, only the ones related to this question)
rcp.mvp.view (rcp.mvp.presenter /
rcp.mvp.model)
rcp.mvp.presenter (rcp.mvp.data -
data reexports the model, so this is
not needed here) *
rcp.mvp.data (rcp.mvp.data.mysql /
rcp.mvp.model / javax.persistence /
org.eclipse.persistence.jpa)
rcp.mvp.data.mysql - provides only
the mysql-jdbc-driver. has to be
inside the classpath
rcp.mvp.model
In this scenario, the JPA provider in the data-plugin is able to load the classes from the model-plugin without a buddy-policy.
*Note, the presenter is not dependent on any JPA packages since this is encapsulated by DAOs (the main reason why to use them still)
Links
User Guide
RCP example (unfortunately not using DAOs)
EclipseLink conceptual Webinar from live.eclipse.org