How to configure embedded Jetty to pick up web fragments? - java

My Java app uses embedded Jetty 9.2.2. I added a library to pom.xml containg web_fragment.xml file. But the fragment is not picked up by Jetty. When I start the application I can see in logs that the library is loaded. However when a request is made to a servlet from the library, the app returns 404.
How to make it to work?
In the app there is a Spring configuration file dispatcher-servlet.xml and the library is included there:
<import resource="classpath:/web.fragment.lib.spring.xml" />
There is no web.xml file, but the app contains spring.xml file with mappings. It uses the dispatcher-servlet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"
default-lazy-init="false">
<context:annotation-config/>
<context:property-placeholder system-properties-mode="FALLBACK" location="classpath:config.properties"/>
<bean name="WebServer" class="org.eclipse.jetty.server.Server" init-method="start">
<property name="connectors">
<list>
<bean name="LocalSocket" class="org.eclipse.jetty.server.ServerConnector">
<constructor-arg ref="WebServer"/>
<property name="host" value="0.0.0.0"/>
<property name="port" value="${jetty.port}"/>
</bean>
</list>
</property>
<property name="handler">
<bean class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<bean class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="sessionHandler">
<bean class="org.eclipse.jetty.server.session.SessionHandler"/>
</property>
<property name="contextPath" value="${context.path}"/>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="dispatcherServlet"/>
<property name="servlet">
<bean class="org.springframework.web.servlet.DispatcherServlet"/>
</property>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="**classpath:dispatcher-servlet.xml**"/>
</map>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="pathSpecs">
<list>
<value>/</value>
</list>
</property>
<property name="servletName" value="dispatcherServlet"/>
</bean>
</list>
</property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
</beans>

Web Fragment auto configuration is a feature of the WebAppContext's Configuration layers.
In your example, you are using neither.
You are using Jetty, in an embedded sense, and are building up the list of servlets manually.
You'll either have to switch to building up your application via a WebAppContext or manually have to add the features that those web fragments provide.
The important thing to understand, is that web fragments are fragments of the webapp descriptor, which is a complicated feature of a webapp, which is something that is tracked by the WebAppContext, which is something that is configured by the list of Configuration layers defined in that specific WebAppContext.

Related

Java - Quartz Job working on Debug Tomcat, but not on separate Tomcat

I configured a Quartz job, which fires in the eclipse's Debug Tomcat that comes with Spring. But if I deploy my application to my separate Tomcat installation, the job doesn't fire.
Here's my quartz-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="de.java.scheduling" />
<bean name="issueSyncJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="de.java.scheduling.IssueSyncJob" />
<property name="durability" value="true" />
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="issueSyncJobDetail" />
<property name="cronExpression" value="0/10 * * ? * MON-FRI" />
</bean>
<!-- Scheduler factory bean to glue together jobDetails and triggers to Configure Quartz Scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="issueSyncJobDetail" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
Any idea what might be the cause for the job not triggering once deployed on my Tomcat?

Spring Webflow's _flowId deprecated

I've been assigned a situation to migrate a spring-webflow-1.0 project to spring-webflow-2.4.
Also I've been asked to maintain the original _flowId identification i.e. /flows.htm?_flowId=booksearch
In order to do so, I've put together the following flow-definition.xml that is loaded by spring. It uses the WebFlow1FlowUrlHandler I've seen mentioned in a couple of places to allow you to maintain WebFlow1 based url matching but none of the following urls are finding anything
http://localhost:8080/SpringWebFlowExamples/flows.html?_flowId=booksearch
http://localhost:8080/SpringWebFlowExamples/flows.html?_flowId=pensionclaims
The definitions for booksearch-flow.xml and pensionclaims-flow.xml are located in webapps/flows but to no avail?
Would anyone have any ideas?
Thanks,
Mark.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry"/>
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<flow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<flow:flow-location-pattern value="/flows/*-flow.xml"/>
</flow:flow-registry>
<flow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator"
development="true"/>
<bean id="internalResourceViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers" ref="internalResourceViewResolver"/>
<property name="useSpringBeanBinding" value="true"/>
</bean>
<bean name="/flows.html" class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor"/>
<property name="flowUrlHandler">
<bean class="org.springframework.webflow.context.servlet.WebFlow1FlowUrlHandler"/>
</property>
</bean>

authenticating Spring Web Service with LDAP

I want to expose a sample Spring web service which is authenticated using LDAP.
First, I have created the web service:
import javax.jws.WebMethod;
import javax.jws.WebService;
import com.domain.SampleEntity;
/**
* Actual web service implementation.
*
*/
#WebService
public class SampleEntityWebService {
/**
* Read and return SampleEntity by a supplied id.
*/
#WebMethod
public SampleEntityByIdResponse readSampleEntityById(Long id) {
SampleEntity sampleEntity = new SampleEntity();
sampleEntity.setId(id);
SampleEntityByIdResponse sampleEntityByIdResponse = new SampleEntityByIdResponse();
sampleEntityByIdResponse.setSampleEntity(sampleEntity);
return sampleEntityByIdResponse;
}
}
Web Service Provider configuration contains:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context" xmlns:ws="http://www.springframework.org/schema/integration/ws"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws-2.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
">
<!-- TOOD: Check if required or not -->
<!-- <bean id="simpleJaxWzServiceExporter"
class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
<property name="baseAddress" value="${ws.base.url}" />
</bean> -->
<!-- <context:component-scan base-package="com.integration.ws.provider" /> -->
<!-- <context:property-placeholder location="classpath:META-INF/spring/web-service.properties" /> -->
<bean id="sampleEntityMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.integration.ws.provider.SampleEntityByIdRequest</value>
<value>com.integration.ws.provider.SampleEntityByIdResponse</value>
<value>com.domain.SampleEntity</value>
</list>
</property>
</bean>
<bean
class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping">
<property name="mappings">
<props>
<prop key="${ws.base.url}/sampleEntityById">sampleEntity-by-id-gateway</prop>
</props>
</property>
<property name="interceptors">
<list>
<ref local="wsSecurityInterceptor" />
</list>
</property>
</bean>
**<bean id="wsSecurityInterceptor"
class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="policyConfiguration" value="classpath:META-INF/securityPolicy.xml" />
<property name="callbackHandlers">
<list>
<ref bean="authenticationHandler"/>
</list>
</property>
</bean>**
<bean id="authenticationHandler"
class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
<property name="userDetailsService">
<bean class="org.springframework.security.core.userdetails.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
${wsUserName}=${wsUserPassword},ROLE_USER
</value>
</property>
</bean>
</property>
</bean>
<ws:inbound-gateway id="sampleEntity-by-id-gateway"
request-channel="sampleEntityRequestById" marshaller="sampleEntityMarshaller"
unmarshaller="sampleEntityMarshaller" reply-channel="sampleEntityResponse" />
<int:channel id="sampleEntityRequestById" />
<int:channel id="sampleEntityResponse" />
<int:service-activator
expression="#sampleEntityWebService.readSampleEntityById(payload.id)"
input-channel="sampleEntityRequestById" output-channel="sampleEntityResponse" requires-reply="true"/>
<int:channel id="sampleEntitys" />
</beans>
The Security policy file referred contains:
<xwss:SecurityConfiguration dumpMessages="true" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:RequireUsernameToken passwordDigestRequired="true" nonceRequired="true"/>
</xwss:SecurityConfiguration>
The service is working fine as such. Now I want to authenticate the users who access this service using LDAP.
I am new to Spring web services and security. Can anyone please suggest about the configuration changes required to integrate a Spring web service with LDAP.
You can change the user details service from InMemoryDaoImpl to LdapUserDetailsService.
The configuration I can derive is:
<bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://monkeymachine:389/dc=springframework,dc=org"/>
<property name="userDn" value="cn=manager,dc=springframework,dc=org"/>
<property name="password" value="password"/>
</bean>
<bean id="ldapPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=groups"/>
<property name="groupRoleAttribute" value="ou"/>
</bean>
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0"
value="ou=People,o=MyCompany,o=Intranet" />
<constructor-arg index="1" value="(uid={0})" />
<constructor-arg index="2" ref="contextSource" />
</bean>
<bean id="authenticationHandler" class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
<property name="userDetailsService">
<bean class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="userSearch">
<constructor-arg ref="ldapPopulator">
</bean>
</property>
</bean>
Be in mind I haven't tried it yet, and most of the part I copied from another source. What you need is a UserDetailsService, and you just need to set that to the authenticationHandler. From the LdapUserDetailsService source code, it needs two constructor, LdapUserSearch, and LdapAuthoritiesPopulator. I googled an example on how to instantiate LdapUserSearch bean and found example from here. I found LdapPopulator bean example from the official documentation.
More details about Ldap Authentication with Spring Security can be found at the official documentation.
I hope you understand about LDAP, because I have no knowledge of LDAP. Good luck.

Context Initialization Failed - Broadleaf Commerce - Send Order Confirmation Email

In the broadleaf demo site, after ordering I have seen..
A confirmation email has been sent to xyz#abc.com
But the email doesn't seem to go because it wasn't configured. I tried making these changes to my applicationContext-email.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- A dummy mail sender has been set to send emails for testing purposes only
To view the emails sent use "DevNull SMTP" (download separately) with the following setting:
Port: 30000 -->
<bean id="blMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host"><value>smtp.mandrillapp.com</value></property>
<property name="port"><value>900</value></property>
<property name="protocol"><value>smtp</value></property>
<property name="username"><value>xyz#abc.com</value></property>
<property name="password"><value>mypassword</value></property>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.timeout">25000</prop>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
<bean id="blEmailTemplateResolver" class="org.thymeleaf.templateresolver.ClassLoaderTemplateResolver">
<property name="prefix" value="emailTemplates/" />
<property name="suffix" value=".html" />
<property name="cacheable" value="${cache.page.templates}"/>
<property name="cacheTTLMs" value="${cache.page.templates.ttl}" />
</bean>
<bean id="blEmailTemplateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolvers">
<set>
<ref bean="blEmailTemplateResolver" />
</set>
</property>
<property name="dialects">
<set>
<bean class="org.thymeleaf.spring3.dialect.SpringStandardDialect" />
<ref bean="blDialect" />
</set>
</property>
</bean>
<bean id="blMessageCreator" class="org.broadleafcommerce.common.email.service.message.ThymeleafMessageCreator">
<constructor-arg ref="blEmailTemplateEngine"/>
<constructor-arg ref="blMailSender"/>
</bean>
<bean id="blMessageCreator" class="org.broadleafcommerce.common.email.service.message.NullMessageCreator">
<constructor-arg ref="blMailSender"/>
</bean>
<bean id="blEmailInfo" class="org.broadleafcommerce.common.email.service.info.EmailInfo">
<property name="fromAddress"><value>support#mycompany.com</value></property>
<property name="sendAsyncPriority"><value>2</value></property>
<property name="sendEmailReliableAsync"><value>false</value></property>
</bean>
<bean id="blRegistrationEmailInfo" parent="blEmailInfo">
<property name="subject" value="You have successfully registered!"/>
<property name="emailTemplate" value="register-email"/>
</bean>
<bean id="blForgotPasswordEmailInfo" parent="blEmailInfo">
<property name="subject" value="Reset password request"/>
<property name="emailTemplate" value="resetPassword-email"/>
</bean>
<bean id="blOrderConfirmationEmailInfo" parent="blEmailInfo">
<property name="subject" value="Your order with The Heat Clinic"/>
<property name="emailTemplate" value="orderConfirmation-email"/>
</bean>
</beans>
I have also seen a class called SendOrderConfirmationEmailActivity class. This class seems to send the email. This is listed in the activities in applicationContext-workflow.xml but I am getting the following exception.
[ERROR] 00:07:19 ContextLoader - Context initialization failed
[artifact:mvn] org.springframework.beans.FatalBeanException: Unable to merge source and patch locations; nested exception is org.broadleafcommerce.common.extensibility.context.merge.exceptions.MergeException: java.lang.NullPointerException
[artifact:mvn] at org.broadleafcommerce.common.extensibility.context.MergeApplicationContextXmlConfigResource.getConfigResources(MergeApplicationContextXmlConfigResource.java:86)
[artifact:mvn] at org.broadleafcommerce.common.web.extensibility.MergeXmlWebApplicationContext.loadBeanDefinitions(MergeXmlWebApplicationContext.java:130)
[artifact:mvn] at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
Could you tell me the way of how to send order confirmation email?
I am using Broadleaf commerce demo 3.1.0-GA version.
You seem to have two blMessageCreator beans defined, the second a NullMessageCreator. I would remove the latter from your configuration and try again.
My configuration is more or less the same as your's except with just the ThymeleafMessageCreator defined. I reproduced your issue by adding the second blMessageCreator definition.
Also you mention seeing the SendOrderConfirmationEmailActivity class. Just be sure to check that you have an implementation of SendOrderConfirmationEmailActivity (if you didn't fork from a recent DemoSite version). You will need to provide this to link it up in the blCheckoutWorkflow which you override in applicationContext-workflow.xml. I believe you can find a demo implementation in the DemoSite app here.
Hope this gets you going.

JBoss 7 Override JNDI Datasource

I have a Spring Web Application with Maven 3 and Datasources/Beans configured for local development on a h2 Database. For Testing there exists a JBoss AS 7.1 Server.
Is it possible to override a Bean / DataSource in a special JBoss XML-File, so that for local (IDE) matters a DriverManagerDataSource is used (see first code posting), and a JndiObjectFactoryBean (second one), if my Application is deployed on a JBoss?
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
<!-- And so on -->">
<!--GENERAL-->
<context:annotation-config/>
<context:component-scan base-package="com.mysuperapp"/>
<!--DATASOURCES-->
<bean id="activitiDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:file:h2\activiti;MVCC=TRUE"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="hibernateDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:file:h2\hibernate;AUTO_SERVER=TRUE"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<!--TXMANAGEMENT-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="mysuperappPersistenceUnit"/>
<property name="dataSource" ref="hibernateDataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.mysuperapp.model"/>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<entry key="hibernate.hbm2ddl.auto" value="update"/>
</map>
</property>
</bean>
<!-- And so on -->
custom applicationContext.xml datasources for JBoss
<bean id="activitiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/activitiDataSource"/>
</bean>
<bean id="hibernateDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/hibernateDataSource"/>
</bean>
Any help is greatly appreciated.
Your application creates the database connection on its own as i can see on your config.
Instead of doing this you could just define the datasource on the app-server and obtain it by a jndi lookup. So you can configure the database connection for each system separately.
<!-- DataSource-LookUp -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="java:jboss/datasources/MyDataSourceDS" />
<property name="resourceRef" value="true" />
</bean>
Your JBoss has a file <jboss_home>/standalone/configuration/standalone.xml which is used if you don't provide a different one.
For testing purposes you could try and make a copy of that file in the same directory, e.g. naming it test.xml and add your datasource definition there. Then use it by starting JBoss with standalone.bat --server-config=test or standalone.bat -c test.
I managed to do this with a SVN patch, which is added prior to the automatic deployment. It changes the DataSource definitions.
Pay attention when creating the patch with windows and applying under linux with /usr/bin/patch (CR+LF problem, apply dos2unix filename to both patch and files to be patched).

Categories