JAX-WS & JSR 330 (Spring) - cannot inject dependency - dependency-injection

I cannot seem to inject a simple bean into my #WebService. With Spring on the classpath and javax.inject dependencies defined, I created a simple JAX-WS webservice with some underlying interface-driven DAOs etc:
#Named
#WebService(name = "NoteStorage", serviceName = "NoteStorageWS")
public class NoteStorageWS implements NoteStore {
private static final Log l = LogFactory.getLog(NoteStorageWS.class);
#Named("NoteDAO")
#Inject
private NoteDAO noteDAO;
public NoteStorageWS() {
super();
}
#Override
#WebMethod
public StorageState takeNote(String note) {
try {
l.info(format("Service received message: '%s'", note));
Note n = new Note();
n.setContent(note);
noteDAO.store(n);
} catch (Exception e) {
l.error(e);
return StorageState.FAILURE;
}
return StorageState.SUCCESS;
}
#WebMethod(exclude = true)
public void setNoteDAO(NoteDAO noteDAO) {
this.noteDAO = noteDAO;
}
}
NoteDAOhas just implementation: FlatFileNoteDAO which is defined as follows:
#Named("NoteDAO")
public class FlatFileNoteDAO implements NoteDAO {
private static final Log l = LogFactory.getLog(FlatFileNoteDAO.class);
#Override
public void store(Note n) {
if (n == null) {
throw new IllegalArgumentException("Note was null");
}
try {
l.info(format("Storing note '%s'", n));
FileWriter fileWriter = new FileWriter(new File("Note"));
fileWriter.write(format("%s\n", n.getContent()));
fileWriter.close();
} catch (IOException e) {
throw new DataAccessException(e);
}
}
}
My web.xml says:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<resource-env-ref>
<description>Object factory for the CDI Bean Manager</description>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
</web-app>
I deploy the application to Glassfish by pointing it to the target/note-ws/ directory and execute the simple takeNote method via the ?Tester page.
Upon submission of the tester form I get a NullPointerException at the line noteDAO.store(n);, presumably because noteDAO wasn't injected.
I can confirm that Spring has been invoked by the logs from glassfish on context initialisation (the Java EE context):
[#|2011-12-04T16:57:24.970+0000|INFO|glassfish3.1.1|org.springframework.context.annotation.ClassPathBeanDefinitionScanner|_ThreadID=256;_ThreadName=Thread-2;|JSR-330 'javax.inject.Named' annotation found and supported for component scanning|#]
[#|2011-12-04T16:57:25.653+0000|INFO|glassfish3.1.1|org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor|_ThreadID=256;_ThreadName=Thread-2;|JSR-330 'javax.inject.Inject' annotation found and supported for autowiring|#]
[#|2011-12-04T16:57:25.757+0000|INFO|glassfish3.1.1|org.springframework.beans.factory.support.DefaultListableBeanFactory|_ThreadID=256;_ThreadName=Thread-2;|Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#9e39146: defining beans [noteStorageWS,NoteDAO,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy|#]
which says my beans are defined: noteStorageWS, NoteDAO and so-on.
Any ideas?
Edit
to clarify, I'm using Spring to provide JSR 330 -- dependency injection -- functionality.

I never got this solved, so I ended up removing the DI-features as the codebase was small and relied on manual dependency resolution - plain old new IFaceImpl(); for now.

JAX-WS and Guice require a specific integration via #GuiceManaged annotation. More info here.

Move the business logic to a separate bean and annotate it with #Configurable so that Spring can handle the lifecycle of the bean. Now use that bean in NoteStorageWS
#Configurable
public class NoteStorageUtil{
#Named("NoteDAO")
#Inject
private NoteDAO noteDAO;
public StorageState takeNote(String note) {
try {
l.info(format("Service received message: '%s'", note));
Note n = new Note();
n.setContent(note);
noteDAO.store(n);
} catch (Exception e) {
l.error(e);
return StorageState.FAILURE;
}
return StorageState.SUCCESS;
}
}
#WebService(name = "NoteStorage", serviceName = "NoteStorageWS")
public class NoteStorageWS implements NoteStore {
public StorageState takeNote(String note) {
return new NoteStorageUtil().takeNote(note)
}
}
Or please check if your end point configuration is proper, so that the web service end point is a spring-managed bean also.
Eg:-
<bean id="hello" class="demo.spring.service.HelloWorldImpl" />
<jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />
check the link

Related

mdui metadata extension with spring-saml

i need to configure an SP with Spring SAML Extension, this time with a new idp admin request.
He ask me to send him metadata with mdui values like this:
<md:SPSSODescriptor> <Extensions> <mdui:UIInfo>
<mdui:DisplayName xml:lang="it">desc</mdui:DisplayName>
<mdui:InformationURL xml:lang="it">http://xxxx</mdui:InformationURL>
</Extensions>
....
</SPSSODescriptor>
I think i can do this operation with a non signed metadata with values added by hand.
It is the only way or can i obtain the same result with configuration options ?
thanks in advance.
Alessandro
Checkout the MetadataGenerator class of spring-security-saml. It has a buildExtensions method that is populating OpenSAML's Extensions object with the DiscoveryResponse extension if configured. You could possibly extend MetadataGenerator and hook in your configuration.
This is an excerpt of the buildExtensions method:
protected Extensions buildExtensions(String entityBaseURL, String entityAlias) {
boolean include = false;
Extensions extensions = new ExtensionsBuilder().buildObject();
// Add discovery
if (isIncludeDiscoveryExtension()) {
DiscoveryResponse discoveryService = getDiscoveryService(entityBaseURL, entityAlias);
extensions.getUnknownXMLObjects().add(discoveryService);
include = true;
}
if (include) {
return extensions;
} else {
return null;
}
}
If you're using Spring Boot you can use this library to configure SAML and provide the custom MetadataGenerator: spring-boot-security-saml
The configuration would look something like:
#Configuration
public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
#Override
public void configure(ServiceProviderSecurityBuilder serviceProvider) throws Exception {
serviceProvider
.metadataGenerator(customGenerator);
}
}

Neo4j database not persisting using Spring Data Neo4j

I'm starting a project using Neo4j and Spring Data Neo4j. I want my program to use a local database that already contains my data (as opposed to loading the data each time on startup) since I have a lot of data that needs to be loaded into the database. I've tried setting up a test case that populates a database with my data in order to accomplish this goal. However, the data in the database does not appear to persist after my tests have finished running: I look at the database using the neo4j console/shell and find it is empty.
I've constructed a small example project that's also not working. Any insight into what I'm doing incorrectly would be appreciated.
Node entity class:
#NodeEntity
public class Entity {
#GraphId private Long graphId;
private String name;
public Entity() { }
public Entity(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Repository class:
public interface EntityRepository extends GraphRepository<Entity> { }
My test class:
#ContextConfiguration(locations = "classpath:applicationContext.xml")
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
public class DatabaseTest {
#Autowired Neo4jTemplate template;
#Autowired EntityRepository entityRepository;
#Test
public void testCreatingEntities() {
Entity entity1 = new Entity("one");
Entity entity2 = new Entity("two");
template.save(entity1);
template.save(entity2);
Iterator<Entity> entityIterator = entityRepository.findAll().iterator();
List<Entity> entityList = IteratorUtils.toList(entityIterator);
System.out.println("Number of entities = " + entityList.size());
for(Entity entity : entityList) {
System.out.println("Entity " + entity.getName());
}
}
}
applicationContext.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"
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/neo4j
http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:spring-configured/>
<context:annotation-config/>
<context:component-scan base-package="personal.neo4j">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<neo4j:config storeDirectory="data/test.db"
base-package="personal.neo4j"/>
<neo4j:repositories base-package="personal.neo4j"/>
<tx:annotation-driven/>
</beans>
Test output:
Running personal.neo4j.DatabaseTest
Number of entities = 2
Entity one
Entity two
Using libraries:
Java 1.7
Spring 3.2.8.RELEASE
Neo4j 2.0.2
Spring Data Neo4j 3.0.2.RELEASE
JUnit 4.11
Thanks for your help,
Thomas
See if this thread helps:
http://forum.spring.io/forum/spring-projects/data/53804-commit-transactions-running-springjunit4classrunner
Looks like SpringJUnit4ClassRunner will rollback all transactions, unless explicitly told otherwise.

Accessing flow state name from filter

I'm working on a large Grails 1.3.7 project and I want to access the flow state name from a filter for logging purposes. I've been googling a lot and the closest answer I could find was: Grails WebFlow State Name, but it only works from within the flow itself.
Is there any way to obtain the state name of the flow that is being executed in current session from outside the flow (the filter)?
Thanks in advance,
Guillermo
After a lot of googling and debugging I managed to produce the following code. It works in a simple application. I'll integrate it with the main application when I come back from holidays and then I'll update this question.
package org.glalejos
import org.springframework.context.ApplicationContext
import org.springframework.webflow.context.ExternalContext
import org.springframework.webflow.context.ExternalContextHolder
import org.springframework.webflow.context.servlet.ServletExternalContext
import org.springframework.webflow.execution.FlowExecution
import org.springframework.webflow.execution.FlowExecutionKey
import org.springframework.webflow.execution.repository.FlowExecutionRepository
class LoggingFilters {
def grailsApplication
String getFlowStateName(def grailsApplication, def servletContext, def request, def response) {
String stateName
if (grailsApplication && servletContext && request && request.queryString && response) {
try {
String strKey = null
String[] keys = request.queryString.split("&")
keys.each{ if (it.startsWith("execution=")) strKey = it.substring(10)}
if (strKey != null) {
ApplicationContext ctx = grailsApplication.mainContext
FlowExecutionRepository fer = ctx.getBean("flowExecutionRepository")
FlowExecutionKey fek = fer.parseFlowExecutionKey(strKey)
ExternalContext previousContext = ExternalContextHolder.getExternalContext()
try {
// You have to set an external context before invoking "fer.getFlowExecution()" or it'll throw a NPE
ExternalContextHolder.setExternalContext(new ServletExternalContext(servletContext, request, response));
FlowExecution fe = fer.getFlowExecution(fek)
stateName = fe.getActiveSession().getState().getId()
} finally {
ExternalContextHolder.setExternalContext(previousContext);
}
} else {
stateName = null
}
} catch(Exception e) {
stateName = null
}
} else {
stateName = null
}
return stateName
}
def filters = {
logData(controller:"*", action:"*") {
before = {
println("Incoming request. Current flow state name is: ${getFlowStateName(grailsApplication, servletContext, request, response)}")
}
after = {
println("Dispatched request. Current flow state name is: ${getFlowStateName(grailsApplication, servletContext, request, response)}")
}
}
}
}
EDIT: The code above is OK to determine the name of the current flow state at a given point in time, but it won't update the Mapped Diagnostic Context of the logging framework as the flow execution evolves. For this purpose it is necessary to implement a org.springframework.webflow.execution.FlowExecutionListener and register it in conf/spring/resources.groovy:
beans = {
myLoggingFlowExecutionListener(org.example.MyLoggingFlowExecutionListener)
}
You have to register this listener bean and the hibernateConversationListener bean in a executionListenerLoader bean, but, for some reason, Spring DSL doesn't work in this case (see EDIT2 below). So here is the resources.xml you can place in the same folder as resources.groovy in order to properly declare your resources:
<?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-2.0.xsd">
<bean id="executionListenerLoader" class="org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader">
<constructor-arg>
<list>
<ref bean="hibernateConversationListener" />
<ref bean="myLoggingFlowExecutionListener" />
</list>
</constructor-arg>
</bean>
</beans>
Each FlowExecutionListener method receives a lot of context information that can be used for logging purposes (I'm ommiting the implementation of this class for clarity).
EDIT2: Failing to add the hibernateConversationListener bean to the executionListenerLoader results in Hibernate exceptions when manipulating domain objects during the lifecycle of the flow. However, Spring DSL doesn't work in this specific case, so I had to declare the required beans using XML format. See http://grails.1312388.n4.nabble.com/Registering-custom-flow-execution-listener-td2279764.html. I've updated the code above to the final, working, version.

struts2 Async Action

Looking to use Struts2 with Serlvet 3.0 Async support.
My first approach was to just handle to writing to the outputstream in the action and returning null. This however returns with a 404 "resource not available". I am attempting to adapt a Bosh servlet inside of a struts action, using ServletRequestAware, ServletResponseAware interfaces to inject the response.
I am using the struts filter dispatcher. Not entirely sure if this is doable,but would be sure happy if someone else has managed to get async to work within a struts action. Perhaps here is an AsyncResult type or someother magic to make this work.
Make sure the struts filter allows async. Here's what that looks like in the web.xml file:
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<async-supported>true</async-supported>
</filter>
Then from within an Action obtain the HttpServletRequest and HttpServletResponse and use the AsyncContext as you would within a servlet:
public String execute() {
HttpServletRequest req = ServletActionContext.getRequest();
HttpServletResponse res = ServletActionContext.getResponse();
final AsyncContext asyncContext = req.startAsync(req, res);
asyncContext.start(new Runnable() {
#Override
public void run() {
try {
// doing some work asynchronously ...
}
finally {
asyncContext.complete();
}
}
});
return Action.SUCCESS;
}

JPA lazy loading Collections in JSF view - better way than using Filters?

Currently I am using a Transaction View pattern to make lazy-loading of collections possible in views.
I have the following in web.xml
<filter>
<filter-name>view</filter-name>
<filter-class>com.jasoni.ViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>view</filter-name>
<url-pattern>*.xhtml</url-pattern>
</filter-mapping>
And the Filter class has the following...
public class ViewFilter implements Filter {
#Resource UserTransaction tx;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
tx.begin();
chain.doFilter(request, response);
}
//catch here
finally {
//another try-catch
tx.commit();
}
}
}
Then assuming I have the following (rather contrived) backing bean
#ManagedBean
#RequestScoped
public class DepartmentEmployees {
#EJB
private DepartmentServiceBean deptService;
#ManagedProperty(value="#{param.deptId}")
private Integer deptId;
private Department dept;
#PostConstruct
public String init() {
dept = deptService.findById(deptId);
}
}
I can do something like this in my view (.xhtml file)
<ul>
<c:forEach var="emp" items="#{departmentEmployees.dept.employees}">
<li>#{emp.firstName} #{emp.lastName}</li>
</c:forEach>
</ul>
Just wondering if anybody knows of a different way to accomplish the same thing without using filters (or servlets).
This approach ("open session in view") has a couple of major disadvantages. Besides being kind of hacky (it's certainly not the design idea of a servlet filter to control a business session) you don't have many options to appropriately process any "real" exception that occurs while rendering the JSF page.
You don't write much about your infrastructure / technology stack, but I assume that you are on a Java EE 6 server.
I usually use the EntityManger in Extended Mode and flush it with transactions which I control explicitly by annotating only certain methods of my business facade. Have a look at this example (taken from Adam Bien - Real World Java EE Patterns, Rethinking Best Practices):
#Stateful
#TransactionAttribute(TransactionAttributeType.NEVER)
public class BookFacadeBean implements BookFacade {
#PersistenceContext(type=PersistenceContextType.EXTENDED)
private EntityManager em;
private Book currentBook;
public Book find(long id){
this.currentBook = this.em.find(Book.class, id);
return this.currentBook;
}
public void create(Book book){
this.em.persist(book);
this.currentBook = book;
}
public Book getCurrentBook() {
return currentBook;
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void save(){
//nothing to do here
}
}
A next level in this approach would be to bind the EntityManager to a CDI conversation scope. Have a look at (a) Weld (b) Seam 3 Persistence for further discussions on that topic.
This is rather a rough sketch of an alternative than a detailed how-to. I hope this level of information is what you were asking about - feel free to ask further questions. :-)

Resources