Dependency Injection: Jetty 7 - java

My application requires several interface implementations which require a Jetty server to do their job. This is, however, not necessarily the case in every implementations of those interfaces so the Jetty server is only a dependency.
Since it would be a huge amount of pain to wrap the entire jetty server with all its logging, connector and Handler configurations, I want to inject the server to those implementations with Spring. I decided that injecting the Server class is not a good idea because an implementation could stop the server even if its required at another location. Currently I inject empty HandlerList classes to those implementations and they register their handlers to avoid those problems.
The Problem: Those handlers might interfere with other handlers for example: implementation one might register a handler for /foo and implementation two too... problem. Has anyone used Jetty in such an environment? And how could this problem be solved?
My XML to clarify my problem:
<bean id="jetty" class="org.eclipse.jetty.server.Server" destroy-method="stop">
<property name="connectors">
<list>
<bean class="org.eclipse.jetty.server.bio.SocketConnector">
<property name="host" value="10.8.0.46" />
<property name="port" value="9999" />
</bean>
</list>
</property>
<property name="handler">
<bean class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="jetty.handlerList" />
<bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
<property name="requestLog">
<bean class="org.eclipse.jetty.server.NCSARequestLog">
<constructor-arg value="${jetty.logfile}" />
<property name="extended" value="false"/>
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
<property name="sendServerVersion" value="false" />
</bean>
<bean id="jetty.handlerList" class="org.eclipse.jetty.server.handler.HandlerList" />
If I require an empty HandlerList I use something like this where com.example.myapp.util.ioc.CreateHandlerListFactory is a org.springframework.beans.factory.FactoryBean which creates a new HandlerList within the given HandlerList.
<constructor-arg>
<bean class="com.example.myapp.util.ioc.CreateHandlerListFactory">
<constructor-arg ref="jetty.handlerList"/>
</bean>
</constructor-arg>

I have a few possible suggestions:
Add an org.eclipse.jetty.servlet.ServletHandler and instead of Jetty-specific Handlers, map standard Servlets instead. You can set the ServletHandler's Servlets either by adding them one-by-one (each wrapped in a ServletHolder) or with setServlets(ServletHolder[] holders). The ServletMappings are set similarly.
You could inject the ServletHandler to each interface implementation to let them add their mapped servlets, or centrally create arrays of ServletHolders and ServletMappings, thereby also preventing duplicated paths by keeping control of the paths out of each interface implementation. The latter would also allow at least the interface implementations to be programmed against the standard Servlet API, making the bulk of your code independent of Jetty.

Related

Manually open a hibernate session with Spring config

The issue I am having is that I use Spring to manage and load hibernate for my web application. I am currently using OpenSessionInViewFilter. This works as intended when I am viewing the application, but not so well when I am trying to access hibernate from non-view related activities such as a Quartz task or some Runnable thread I create to help with some tasks. This causes the Lazy initialize exception and no session available exceptions to occur.
Here is how I currently use Spring to manage Hibernate
<bean id="mainDataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
[..DB config..]
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="mainDataSource"/>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
<property name="dataSource"><ref local="mainDataSource"/></property>
</bean>
I then configure DAO objects which extend HibernateDaoSupport and inject them into service classes
<bean id="myDAO"
class="package.myDAO">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="mySvcTarget" class="package.myService">
<property name="myDAO"><ref bean="myDAO"/></property>
</bean>
<bean id="myService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="txManager"/>
</property>
<property name="target">
<ref bean="mySvcTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
So then in my application, myService is injected into my controller classes so I use that to get access to my DAO's. For my situation though it appears I need to access my DAO's (or service preferably) some other way and manually open and close my hibernate sessions since my service classes only seem to be open during view session. I am not exactly sure the best way to do this. All the hibernate configurations are there already in Spring so I'm assuming its just a matter or calling them somehow.
First of all those additional services that you're using (non-views) should be visible by Spring. The simplest way to do it is to use #Service annotation. And to make it work you can add <context:component-scan base-package="your.package"> in your configuration.
After this, if Spring sees your service as a bean, it should be enough to use #Transactional annotation to have Hibernate session in it.

How to define separate wsdl for different services in a same spring-WS project?

I'm new to Spring -WS and so I'm looking for some suggestion on Spring web services.
I'm trying to create web services for my company product. There are two sets of services for two different targets. But I don't want to create two different projects, as I don't want to pass around 2 *.war to the clients and also at lower levels have lot of mutual dependencies.
So, I would like some suggestion/advice on how to generate two(or multiple) WSDL files. so the two different WSDL files will be accessible from different locations.
I tried using only one servlet, creating and binding all the beans in it(spring-ws-servlet.xml) and tried to create two different dynamic wsdl(I created two different schema files and set different values for "schema"). But it didn't work.
So, could anyone guide me which way is architecturally better and is in line with best-practises?
Thanks in advance,
Now, I was wondering what is the best way to accomplish this. Should I define two different servlets in web.xml and create two sets of mapping, or simply define two beans that generate different wsdl in *-servlet.xml(spring mapping file),if then how, thereby creating only one set of mapping.
The easiest, I guess its tedious approach but what I did was that I added a new bean for a different 1+ service in the; i call it wiring config file (also known as application.xml, spring-config.xml).
So this what I had:
<bean id="SmallBusinessAccount" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition" lazy-init="true">
<property name="schemaCollection">
<bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="inline" value="true" />
<property name="xsds">
<list>
<value>schemas/SmallBusinessAccountSerivceOperations.xsd</value>
</list>
</property>
</bean>
</property>
<property name="portTypeName" value="SmallBusinessAccountService"/>
<property name="serviceName" value="SmallBusinessAccountServices" />
<property name="locationUri" value="/endpoints"/>
</bean>
<bean id="CreditManagement" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition" lazy-init="true">
<property name="schemaCollection">
<bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="inline" value="true" />
<property name="xsds">
<list>
<value>schemas/CreditManagementServiceOperations.xsd</value>
</list>
</property>
</bean>
</property>
<property name="portTypeName" value="CreditManagementService"/>
<property name="serviceName" value="CreditManagementServices" />
<property name="locationUri" value="/endpoints"/>
</bean>
This will generate different wsdls for different service implementations in a same project.
I don't know if there is a better approach; like inject list of services to a single bean that generate isolated wsdls for each of those services.

How to create prototype instances of "targetObject" using "MethodInvokingJobDetailFactoryBean" in Spring-Quartz?

I've been playing around with Spring-Quartz for a while now, and there is one thing I'm unable to achieve - I want to use the "MethodInvokingJobDetailFactoryBean" in order to execute a method in an class I have, and I want new instance of that object created each time the trigger is triggered.
The part of my application context that is related to Quartz looks like this:
<bean id="myTask" class="com.test.TestImpl" scope="prototype" /> <!-- The bean that does the actual work -->
<bean id="testMethodJobDetailBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myTask"/>
<property name="targetMethod" value="run"/>
<property name="concurrent" value="false"/>
</bean>
<bean id="testTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="testMethodJobDetailBean"/>
<property name="startDelay" value="25000"/>
<property name="repeatInterval" value="5000"/>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="triggers">
<list>
<ref bean="testTrigger"/>
</list>
</property>
</bean>
My objects' names are different in the original file, and I have 2 more jobs (with a trigger for each of them) but they are not relevant for my question.
The above configuration works, and my task is executed every 5 seconds. The problem is, it always uses the same "com.test.TestImpl" instance which is problematic for me since the object have state that affects its behavior.
I've read that Quartz's default behavior is to create a new instance of jobs each time, but when using Spring-Quartz, Spring manages the life-cycle. This indeed seems logical, and that's why I added the scope="prototype" to the "myTask" bean, but it didn't help.
I also tried to set the scope of the JobDetailsFactory bean to prototype, and it didn't help.
I think that the problem is that the JobDetail object created by "MethodInvokingJobDetailFactoryBean" is not defined as prototype, and since is it wrapping my bean, and being created only once - my bean won't be created more than once.
I would like to know if someone else encountered this as I wasn't able to find any useful information regarding this issue, and wasn't able to find anyone that experienced the same behavior.
And of course, if you know how to fix this, I would be happy to hear about it.

Marshalling Different Classes with Spring MVC and JIBX

We are trying to build some RESTful services with Spring MVC. We will be providing several representations: XML, HTML, & JSON. We would like to use JiBX as the OXM technology.
We are currently having difficulty figuring out how to wire up Spring with JiBX. If we want to wire up a single class, for example Customer, we simply define a JibxMarshaller, an XML MarshallingView, and add it too our ContentNegotiatingViewResolver. This works great.
The problem is we aren't sure how to wire up marshalling of multiple classes, for example, Customer and User. Each JibxMarshaller can support only one class (unlike the Jaxb2Marshaller which can support many). We tried declaring a marshaller for each class, but the MarshallingView only support one marshaller. Declaring multiple MarshallingViews does not work (it appears only the first one works).
Your advice is appreciated. Thanks.
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<util:map>
<entry key="xml" value="application/xml"/>
</util:map>
</property>
<property name="defaultViews">
<util:list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="userMarshaller"/>
</bean>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="customerMarshaller"/>
</bean>
</util:list>
</property>
</bean>
<bean id="userMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass" value="com.mycompany.User"/>
</bean>
<bean id="customerMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass" value="com.mycompany.Customer"/>
</bean>
Update based on Ritesh's answer below:
It turns out that I was thrown off by the targetClass property of the JibxMarshaller. I thought it meant the marshaller would only work for a single class, however, it appears to just uses the target class as a way of finding all related bindings. So, the solution is to use just a single marshaller, using an arbitrary target class from your set of classes you have bindings for. For example:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<util:map>
<entry key="xml" value="application/xml"/>
</util:map>
</property>
<property name="defaultViews">
<util:list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="jibxMarshaller"/>
</bean>
</util:list>
</property>
</bean>
<bean id="jibxMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass" value="com.mycompany.User"/>
</bean>
JiBX binding compiler adds JiBX_bindingList field to class files. At run time, the 'targetClass' (any compiled class with JiBX_bindingList field) is used to build a BindingFactory. It is the getMappedClasses() of IBindingFactory which is used by JibxMarshaller
in supports() method to check if marshaller can marshal a class.
Please also see JiBX runtime usage.

How can I define multiple sessionfactory instances in Spring?

I would like to have multiple Hibernate SessionFactories in a spring application, all of them with identical configurations except for the DataSource. Ideally, I would acquire a particular SessionFactory by name. I need to be able to do this based on runtime state, and it isn't possible to determine which session factories I will need at application startup time. Basically, I need a SessionFactoryTemplate or something like it.
Is this possible? How do I go about doing it?
You might define an abstract bean and use bean inheritance. This means you'll have a bean definition that works as a template and you may have multiple beans just copying the attributes set by the parent bean.
Here's an example:
<bean id="abstractSessionFactory" abstract="true"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
<bean id="mySessionFactory" parent="abstractSessionFactory">
<property name="dataSource" ref="myDataSource"/>
...
</bean>
<bean id="mySessionFactory2" parent="abstractSessionFactory">
<property name="dataSource" ref="myDataSource2"/>
...
</bean>
Using the attribute 'abstract' you ensure that bean won't be instantiated and it will be used just as a template.
More info here: link text
Are you sure you need multiple SessionFactories? If all the mappings/configurations are the same and you just have multiple identical databases (e.g. in a multi-tenant app?), then how about having a single SessionFactory that connects to a DataSource which dynamically supplies the appropriate database connection?
See this question for more details:
And this blog post on Dynamic DataSource Routing in Spring.
I have no idea what your current bean definition looks like now, but wouldn't you just ... define a second SessionFactory?
<bean id="mySessionFactory1"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource1"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
<bean id="mySessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource2"/>
...
</bean>
You could then simply just wire your DAOs up with one sessionFactory vs the other:
<bean id="myProductDao" class="product.ProductDaoImpl">
<property name="sessionFactory" ref="mySessionFactory1"/>
</bean>
<bean id="myCompanyDao" class="product.ProductDaoImpl">
<property name="sessionFactory" ref="mySessionFactory2"/>
</bean>
I don't know of an easy solution for your problem using Spring.
However, you could be able to use Hibernate Interceptors, provided that your particular databases/data-sources can be reached through one master/admin database connection. This blog post explains how in detail, but the gist of it is to dynamically replace table names in SQL statements that Hibernate generates, with qualified names identifying different databases. This is relatively easy to understand and maintain, and works well in my company's multi-tenant set-up.
Apart from that, you can try writing your own TransactionManager, using the HibernateTransactionManager as a starting point, adding support for working with multiple session factories. However, this would mean you having to really dive into Spring ORM support internals, and that is something I tried, but then scrapped in favor of the first approach. I'm sure it can be done with moderate effort, but the previous solution was already doing the job for us.

Categories

Resources