I am new to Spring and Hessian and never used them before.
I want to write a small Hello World Program which clearly shows how this service works.
I am using Maven for list project details and dependencies.
The resources for hessian available online are not complete step-by-step guide.
would appreciate if I get help form someone who has worked writing hessian services
The steps for implementing a Hessian-callable service are:
Create a Java interface defining methods to be called by clients.
Write a Java class implementing this interface.
Configure a servlet to handle HTTP Hessian service requests.
Configure a HessianServiceExporter to handle Hessian service requests from the servlet by delegating service calls to the Java class implementing this interface.
Let's go through an example. Create a Java interface:
public interface EchoService {
String echoString(String value);
}
Write a Java class implementing this interface:
public class EchoServiceImpl implements EchoService {
public String echoString(String value) {
return value;
}
}
In the web.xml file, configure a servlet:
<servlet>
<servlet-name>/EchoService</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>/EchoService</servlet-name>
<url-pattern>/remoting/EchoService</url-pattern>
</servlet-mapping>
Configure an instance of the service class in the Spring application context:
<bean id="echoService" class="com.example.echo.EchoServiceImpl"/>
Configure the exporter in the Spring application context. The bean name must match the servlet name.
<bean
name="/EchoService"
class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="echoService"/>
<property name="serviceInterface" value="com.example.echo.EchoService"/>
</bean>
The client has to create a proxy of the remote interface. You could simply write a JUnit-Test:
HessianProxyFactory proxyFactory = new HessianProxyFactory();
proxyFactory.setHessian2Reply(false);
proxyFactory.setHessian2Request(false);
com.example.echo.EchoService service = proxyFactory.create(
com.example.echo.EchoService, "http://localhost:8080/<optional-context/>remoting/EchoService");
Assert.equals(service.echoString("test"), "test");
Related
we are in the process of converting current spring project into spring boot and at the same time converting all spring beans from xml to java config based.
i am stuck converting camel xml configuration into java based config.
currently we are specified camel config , routes and endpoints , one example as below
<camel:camelContext id="camelClient">
<camel:template id="camelTemplate"/>
</camel:camelContext>
<template id="camelTemplate"/>
here are couple of endpoints
<endpoint id="archiveUserQueue"
uri="swiftmq:${hk.jms.archive.queue.name}?concurrentConsumers=${hk.jms.archive.queue.consumers}"/>
<endpoint id="directSmsNotification" uri="direct:sendSMS"/>
one of the routes defined
<route>
<from ref="directSmsNotification"/>
<to uri="bean:messengerService?method=sendSmsMessage"/>
</route>
in java code we access the end point as below
smsEndpoint = _camelContext.getEndpoint("directSmsNotification");
how can we convert the camel config from xml to java based config.
i have followed instructions specified at http://camel.apache.org/spring-java-config.html but it was too hard to understand as i am not familiar with Camel.
You can mix and match Spring Java config with Apache Camel XML config. I question why you're doing this conversion in the first place.
That said, if you look at the camel docs you'll see there's an example for working with RouteBuilder.
You could also look at the sample spring-boot application. Here's a modified RouteBuilder from that example:
#Component
public class MySpringBootRouter extends RouteBuilder {
#Override
public void configure() {
Context context = getContext();
MyEndpoint ep = context.getEndpoint("someURI", MyEndpoint.class);
from(ep)
.transform().simple("ref:myBean")
.to("log:out");
}
}
Update: I modified the snippet to show getting an Endpoint directly. You can get more info in the Camel docs. I'm not sure how common this approach is. Back when I was using Camel regularly the endpoints were configured declaratively through their URI values. I don't think I ever explicitly defined an endpoint in my Camel XML or Java code. I'm sure there are use cases for it but it might be simpler for you to configure just by URI.
Greetings dear Stackoverflow users, I have been lately in lots of pain with one specific problem with axis2 web services with Spring framework. I have read lots of different guides and read different forums but found people with the same problems but with no solutions. Basically ended up holding the monitor with both of my hands and yelling "What did you find out BudapestHacker938?". Anyway my axis2 web service class needs Spring beans and therefore they are autowired inside the web service class. Everything works so well inside the jetty server where I have servletContext. Just define needed listeners in web.xml and it works. Such a bliss. But unfortunately all good things come to the end in some point, for me, the devil is CICS environment inside of mainframe. There is no servletcontext like in Jetty/Tomcat, luckily it still has axis2 support. So according to the different user-guides I decided to archive my web-service into .aar and added it under the services folder. Axis2 folder structure is the following:
repository/
modules
services
When I am building this .aar archive then I am also generating my own wsdl, not using axis2 inbuilt wsdl generator which according to services.xml generates the services out of the given class (when I am running the axis2server, not using because doesn't like JAX-WS annotations as far as I know). To initialize Spring framework, I needed to write little SpringInit class which initializes Spring beans. Unfortunately it also for some reason initializes my web-service class according to its annotations and then occupies the main port(suspect that SpringInit intializes by its own the web service class since it is also defined as a Spring bean and SpringInit extends Axis2 class ServiceLifeCycle) and I get JVM BIND exception where it is stating that address is already in use. I would like to have the service built up according to the wsdl which is stored inside of the WSDL rather than generate new one, because I have various environments: 1) local machine - Jetty 2) mainframe. Anyway I give an insight to my services.xml:
<service name="Absence" class="org.services.SpringInit">
<description>
random description
</description>
<parameter name="ServiceTCCL">composite</parameter>
<parameter name="useOriginalwsdl" locked="false">true</parameter>
<parameter name="ServiceObjectSupplier">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
<parameter name="ServiceClass">org.services.Absence</parameter>
<parameter name="SpringBeanName">absence</parameter>
<parameter name="SpringContextLocation">META-INF/applicationContextAar.xml</parameter>
</service>
Spring applicationContextAar.xml, little bit refactored it for dear Stack community:
<beans>
<bean id="applicationContext" class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:tcp://localhost/~/devDb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="absence" class="org.services.Absence"></bean>
<bean id="jtemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="ds"></constructor-arg>
</bean>
<bean id="datasetFactory" class="org.vsam.DataSetFactory"></bean>
<bean id="dataManagerFactory" class="org.datamanager.DataManagerFactory"></bean>
<bean id="absenceFactory" class="org.services.AbsenceFactory"></bean>
<bean id="h2Database" class="org.dataset.H2Database"><constructor-arg ref="jtemplate"></constructor-arg>
</bean>
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"></bean>
</beans>
My SpringInit class looks something like that:
public class SpringInit implements ServiceLifeCycle {
public void startUp(ConfigurationContext ignore, AxisService service) {
try {
ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new
ClassPathXmlApplicationContext(new String[] {"applicationContextAar.xml"}, false);
appCtx.setClassLoader(classLoader);
appCtx.refresh();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void shutDown(ConfigurationContext ctxIgnore, AxisService ignore) {}
}
Now we are moving to org.services.Absence.class, it is an ordinary JAX-WS web-service class with following header (contains JAX-WS annotations):
#WebService(name = "AbsenceService", serviceName = "Absence", portName = "Absence",
targetNamespace = "http://www.something.org/Absence")
public class Absence extends ServiceHandlerBase {
#Autowired
private AbsenceFactory absenceFactory;
#Autowired
private DataManagerFactory dataManagerFactory;
#Autowired
private DataSetFactory dataSetFactory;
...
}
Containing methods like that:
#WebMethod
#WebResult(name = "AbsenceResponse")
public SearchAbsenceRecordsResponse invokeSearchAbsenceRecords(
#WebParam ServiceRequest request,
#WebParam SearchAbsenceRecordsRequest absenceRequest) {...}
One alternative is to add "servicejars" folder into "repository" folder and populate it with absence.jar which has all its dependencies in the sub-folder "lib". Axis2 then automatically runs absense.jar since it has JAX-WS annotation. But in there when I call out the web-service for example with SOAP-UI, it doesn't have Spring initialized since I don't know how to initialize Spring in that solution. Maybe someone has any expertise about that.
TL;DR
How do I get my Spring beans initialized in manner that it doesn't start the services in the web service class according to the annotation and would rather build up services according to the wsdl?
You are welcome to ask questions.
How I initialized Spring inside of CICS without servletcontext?
Basically until today the SOAP web services have been published through servicejars which means into the repository folder has been created "servicejars" folder which cointains jars which have been built from the web service classes. "servicejars" subfolder "lib" contains all the dependencies which web service jars need.
At first I learnt from the web(Axis2 homepage, there was an instruction about axis2 and spring integration) for initializing Spring in Axis2 web service I need .aar archive and SpringInit service defined in services.xml. But this brought lots of problems since having old architecture built on jaxws and jaxb there was a huge need for refactoring the web services layer. Axis2 tolerated jaxws annotations only with "servicejars" solution. Initing Spring with SpringInit class meant that it initializes Spring beans according to the application context. This now runs web service bean(absence bean in previous post) as a separate web service and occupied 8080 port, when time came for the web service creation according to WSDL I got an error "JVM bind address already in use". So after that I figured I should create the service according to the absence Spring bean and let axis2server generate the WSDL, but axis2server didn't like jaxws annotation and even without them it didn't like my jaxb DTOs.
Therefore, I decided to drop .aar architecture and went back to the "servicejars" architecture. Unfortunately in there I didn't have services.xml support, to define the potential SpringInit service.
Since jaxws web services are the only entrypoints then I decided do the following (initialize Spring beans in the web service layer):
#WebService(name = "AbsenceService", serviceName = "Absence", portName = "Absence",
targetNamespace = "http://www.something.org/Absence")
public class Absence extends ServiceHandlerBase {
private static AbsenceFactory absenceFactory;
private static DataManagerFactory dataManagerFactory;
private static DataSetFactory dataSetFactory;
static {
try {
ClassPathXmlApplicationContext appCtx = new
ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"}, false);
appCtx.refresh();
absenceFactory = (AbsenceFactory) appCtx.getBean("absenceFactory", AbsenceFactory.class);
dataManagerFactory = (DataManagerFactory) appCtx.getBean("dataManagerFactory", DataManagerFactory.class);
dataSetFactory = (DataSetFactory) appCtx.getBean("datasetFactory", DataSetFactory.class);
} catch (Exception ex) {
ex.printStackTrace();
}
}
...
}
As you can see when this class is being called out, it will initialize applicationcontext and since it is static, all the spring beans will stay in the memory until the end(when service is closed). In other classes autowiring works perfectly, no need to get these beans wired manually.
In the end, I didn't find the possiblity to initialize Spring in the matter as I hoped through .aar architecture, but I found a work around with the guidance of a senior programmer. Huge thanks to him! And now the possible solution is visible for all StackOverFlow users.
EDIT:
In applicationContext.xml I had:
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"/>
Tries to create web services with Absence.class(absence bean). Removed it since I can in local machine as well use pre-generated WSDL with Jetty (originally was used for creating web service in the local machine, like I said before, I have local development environment and it should be also compatible with CICS, now it is solved).
I wrote a simple client server architecture that helps me producing PDF files out of MS Office documents. The communication is handled via RMI and Spring wraps the entire complexity on the server side.
I cannot use Spring on the client side, because I call the methods from Matlab 2007b. A Jar with dependencies to spring produces exceptions due to the special handling of static and dynamic classpaths in Matlab.
Long story short: I wrote a simple RMI client in plain java:
import com.whatever.PDFCreationService;
Object service = Naming.lookup("rmi://operations:1099/pdfCreationService");
System.out.println((PDFCreationService)service); //produces ClassCastException
Interface:
public interface PDFCreationService {
public PDFCreationConfig createPDF(PDFCreationConfig config) throws IOException, InterruptedException, OperationInterruptionException;
}
Extracted out of my "former" spring config (client side):
<bean id="pdfCreationService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://operations:1099/pdfCreationService"/>
<property name="serviceInterface" value="com.whatever.creator.PDFCreationService"/>
</bean>
and on the server side :
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="pdfCreationService"/>
<property name="service" ref="pdfCreationService"/>
<property name="serviceInterface" value="com.whatever.creator.PDFCreationService"/>
<!-- defaults to 1099 -->
<property name="registryPort" value="1099"/>
</bean>
When I run the code the following exception is thrown:
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.whatever.creator.PDFCreationService
I am 100% sure that I do not try to cast to a class like in this post: "ClassCastException: $Proxy0 cannot be cast" error while creating simple RMI application
Does spring encapsulate my interface in a different interface? Is there a way to find out which interface the Proxy hides?
Please let me know if you need more details to clarify my issue.
The RmiServiceExporter exports a RmiInvocationHandler if the remote service don't implements Remote, (ie, not is a traditional RMI Server)
If you can't use a RmiProxyFactoryBean in the client side, that is a bean factory for service interface proxies that convert service calls to RemoteInvocations, seems better option to use traditional RMI instead.
You can use the RmiServiceExporter to export tradional RMI Services too, like
public interface PDFCreationService extends Remote {
public PDFCreationConfig createPDF(PDFCreationConfig config) throws RemoteException;
}
I have a RESTful web service developed using Spring MVC and without any configuration I can return objects from my #ResponseBody annotated controller methods that get serialized to JSON. This works as soon as the Accept header in the request is not set or is application/json.
As I'm getting inspired by the GitHub API specification, I wanted to implement custom mime type for my API as GitHub does, for example: application/vnd.myservice+json. But then I need to tell Spring MVC that my controllers can provide this mime type and that it should be serialized by Json (i.e org.springframework.web.servlet.view.json.MappingJacksonJsonView class).
Any idea how to do it?
You can probably do exactly what is being done with org.springframework.http.converter.json.MappingJacksonHttpMessageConverter. Since it is not a final class, you can derive your converter from this one this way:
class MyCustomVndConverter extends MappingJacksonHttpMessageConverter{
public MyCustomVndConverter (){
super(MediaType.valueOf("application/vnd.myservice+json"));
}
}
then register your converter this way:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="MyCustomVndConverter "/>
</mvc:message-converters>
</mvc:annotation-driven>
It should just work with these changes
How can I implement Restlet framework with my Java EE application?
I have already tried my hands with Spring's Restful Webservice but not sure how to get started with Restlet framework.
Is it a better option than Spring MVC's RESTful implementation? What are the pros and cons of these two frameworks.
The strength of Restlet is that it provides complete API for REST, flexibility when using REST principles and also addresses both client and server sides.
Another aspect you can consider is that Restlet is a complete RESTful middleware allowing connecting various and heterogeneous systems using the REST architecture. As a matter of fact, Restlet can be executed on several environments (Java, Java EE, Android, GWT, Google App Engine) and cloud platforms (EC2, GAE, Azure) with the same API in order to provide RESTful applications. It internally addresses specificities and limitations of each environment. It also allows accessing different types of REST services (like OData, S3...), integrating security of different systems (AWS, Google...) and provide support to the SDC technology of Google (accessing intranet resources in a secure way).
Now let's enter in code. The best approach to implement a Restlet application within JavaEE is to use the servlet extension which plays the role of a front controller to this application. You can then define your entities (Application, ServerResource) as usually. You have to create the following things:
Restlet application (a sub class of Application):
public class ContactApplication extends Application {
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/contact/{id}",
SimpleContactServerResource.class);
return router;
}
}
One or more server resources:
public class SimpleContactServerResource
extends ServerResource {
private ContactService contactService = (...)
#Get
public Representation getContact(Variant variant) {
Map<String, Object> attributes
= getRequest().getAttributes();
String contactId = (String) attributes.get("id");
Contact contact = contactService.getContact(contactId);
return new JacksonRepresentation<Contact>(contact);
}
(...)
}
Configures the Restlet servlet:
<web-app>
<context-param>
<param-name>org.restlet.application</param-name>
<param-value>org.restlet.gtug.gae.ContactsApplication</param-value>
</context-param>
<servlet>
<servlet-name>ServerServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServerServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Hope it helps you and gives a better view of the framework.