We secure our REST services (for server to server communication, no user involved) with Spring Security OAuth2. However when one tries to access a protected resource in a browser, it will show:
<oauth>
<error_description>
An Authentication object was not found in the SecurityContext
</error_description>
<error>unauthorized</error>
</oauth>
We want this to be a custom page of our own choosing. Is there a way?
Setting the access-denied-page won't do. For one it requires the definition of a login page which we don't have as this is a pure server to server communication. For another this attribute is supposedly deprecated since Spring 3.0.. or something.
Anyway.. Debugged my way into the OAuth Error Handling. And found that the response seems to somehow get enriched with the information I see on the error page. Apparently no page rendering at all is done so it looks like there is no error page to replace..?!
At least we want to hide the fact that we use OAuth and just display a basic "Denied" text if we can't have a "real" page.. So maybe I'll have to extend the spring security handler or add a custom filter to modify the response?!
Maybe a redirect to our error page?
Thanks!
Edit
For our current setup check my other SO question here
I had to remove the oauth detail too and my solution was to implement my own OAuth2ExceptionRenderer
package org.some.nice.code;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.oauth2.provider.error.OAuth2ExceptionRenderer;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
public class HeaderOnlyOAuth2ExceptionRenderer implements OAuth2ExceptionRenderer
{
private final Log logger = LogFactory
.getLog(MyOAuth2ExceptionRenderer.class);
public void handleHttpEntityResponse(HttpEntity<?> responseEntity,
ServletWebRequest webRequest) throws Exception
{
if (responseEntity == null)
{
return;
}
HttpInputMessage inputMessage = createHttpInputMessage(webRequest);
HttpOutputMessage outputMessage = createHttpOutputMessage(webRequest);
logger.info("filtering headers only...");
if (responseEntity instanceof ResponseEntity
&& outputMessage instanceof ServerHttpResponse)
{
((ServerHttpResponse) outputMessage)
.setStatusCode(((ResponseEntity<?>) responseEntity)
.getStatusCode());
}
HttpHeaders entityHeaders = responseEntity.getHeaders();
if (!entityHeaders.isEmpty())
{
outputMessage.getHeaders().putAll(entityHeaders);
}
}
private HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest)
throws Exception
{
HttpServletRequest servletRequest = webRequest
.getNativeRequest(HttpServletRequest.class);
return new ServletServerHttpRequest(servletRequest);
}
private HttpOutputMessage createHttpOutputMessage(
NativeWebRequest webRequest) throws Exception
{
HttpServletResponse servletResponse = (HttpServletResponse) webRequest
.getNativeResponse();
return new ServletServerHttpResponse(servletResponse);
}
}
Then you will have to reference it within your spring context
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="theRealm" />
<property name="exceptionRenderer" ref="headerOnlyExceptionRender" />
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="theRealm/client" />
<property name="typeName" value="Basic" />
<property name="exceptionRenderer" ref="headerOnlyExceptionRender" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
<property name="exceptionRenderer" ref="headerOnlyExceptionRender" />
</bean>
<bean id="headerOnlyExceptionRender" class="org.some.nice.code.HeaderOnlyOAuth2ExceptionRenderer"/>
Hope it helps.
Related
In my Spring mvc application, calling following method , when click 'Save' button in jsp page.
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addUser(#ModelAttribute("user") #Valid User u,
BindingResult result, #ModelAttribute("category") UserCategory uc,
BindingResult resultCat, Model model, RedirectAttributes reDctModel) {
this.userService.addUser(u); // adding new user to DB
reDctModel.addFlashAttribute("msgSucess","Successfully saved..!");
this.sendEmail(u.getUsr_email(),"RDMS","Login Details"); // For sending mail
return "redirect:/users";
}
public String sendEmail(String recipientAddress,String subject,String message) {
// creates a simple e-mail object
SimpleMailMessage email = new SimpleMailMessage();
email.setTo(recipientAddress);
email.setSubject(subject);
email.setText(message);
// sends the e-mail
this.mailSender.send(email);
return "Result";
}
This is my applicationcontext
</bean>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="myemailaddress#gmail.com" />
<property name="password" value="********" />
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
The issue is, after adding sendEmail() ,it takes around 15 seconds to save the new record.Before adding this method it takes only 1 second.Can anybody guide me to reducing slowness of the programme or calling sendEmail() after finishing first transaction.Thanks in advance.
You have to create async service and configure your application for asynchronous usage, here you have spring tutorial. In async service you have to place your code for sending email. Below you can see sample code for 2 classes first is service second is application class,
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
#Service
public class SampleService {
#Async
public Future sendEmail(String email) {
// here you can place your code for sending email
return new AsyncResult("email sent successful");
}
}
import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
#SpringBootApplication
#EnableAsync
public class Application implements CommandLineRunner {
#Autowired
SampleService sampleService;
#Override
public void run(String... args) throws Exception {
Future page1 = sampleService.sendEmail("test#gmail.com");
while (!page1.isDone()) {
Thread.sleep(10);
}
System.out.println(page1.get());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I am trying to get my Spring rest controller to return jsonp but I am having no joy
The exact same code works ok if I want to return json but I have a requirement to return jsonp
I have added in a converter I found source code for online for performing the jsonp conversion
I am using Spring version 4.1.1.RELEASE and Java 7
Any help is greatly appreciated
Here is the code in question
mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="parameterName" value="mediaType" />
<property name="ignoreAcceptHeader" value="false"/>
<property name="useJaf" value="false"/>
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml" />
<entry key="html" value="text/html" />
<entry key="jsonp" value="application/javascript" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml"/>
</map>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="contentNegotiationManager" ref="contentNegotiationManager" />
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/templates/slim/${views.template.directory}/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="com.webapp.handler.MappingJacksonJsonpView" />
</list>
</property>
</bean>
</beans>
com.webapp.handler.MappingJacksonJsonpView
package com.webapp.handler;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
public class MappingJacksonJsonpView extends MappingJackson2JsonView {
/** Local log variable. **/
private static final Logger LOG = LoggerFactory.getLogger(MappingJacksonJsonpView.class);
/**
* Default content type. Overridable as bean property.
*/
public static final String DEFAULT_CONTENT_TYPE = "application/javascript";
#Override
public String getContentType() {
return DEFAULT_CONTENT_TYPE;
}
/**
* Prepares the view given the specified model, merging it with static
* attributes and a RequestContext attribute, if necessary.
* Delegates to renderMergedOutputModel for the actual rendering.
* #see #renderMergedOutputModel
*/
#Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
LOG.info("Entered render Method :{}", request.getMethod());
if("GET".equals(request.getMethod().toUpperCase())) {
LOG.info("Request Method is a GET call");
Map<String, String[]> params = request.getParameterMap();
if(params.containsKey("callback")) {
String callbackParam = params.get("callback")[0];
LOG.info("callbackParam:{}", callbackParam);
response.getOutputStream().write(new String(callbackParam + "(").getBytes());
super.render(model, request, response);
response.getOutputStream().write(new String(");").getBytes());
response.setContentType(DEFAULT_CONTENT_TYPE);
}
else {
LOG.info("Callback Param not contained in request");
super.render(model, request, response);
}
}
else {
LOG.info("Request Method is NOT a GET call");
super.render(model, request, response);
}
}
}
Controller Method In Question
#RequestMapping(value = { "/sources"}, method = RequestMethod.GET,
produces={MediaType.ALL_VALUE,
"text/javascript",
"application/javascript",
"application/ecmascript",
"application/x-ecmascript",
"application/x-javascript",
MediaType.APPLICATION_JSON_VALUE})
#ResponseBody
public Object getSources(#PathVariable(value = API_KEY) String apiKey,
#RequestParam(value = "searchTerm", required = true) String searchTerm,
#RequestParam(value = "callBack", required = false) String callBack) {
LOG.info("Entered getSources - searchTerm:{}, callBack:{} ", searchTerm, callBack);
List<SearchVO> searchVOList = myServices.findSources(searchTerm);
if (CollectionUtils.isEmpty(searchVOList)) {
LOG.error("No results exist for the searchterm of {}", searchTerm);
return searchVOList;
}
LOG.debug("{} result(s) exist for the searchterm of {}", searchVOList.size(), searchTerm);
LOG.info("Exiting getSources");
return searchVOList;
}
**Jquery Ajax Code **
$.ajax({
type: "GET",
url: "http://localhost:8080/my-web/rest/sources,
data: {
"searchTerm": request.term
},
//contentType: "application/json; charset=utf-8",
//dataType: "json",
contentType: "application/javascript",
dataType: "jsonp",
success: function(data) {
alert("success");
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Failure");
}
});
A snippet of the error stacktrace that I get is as follows
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:168) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:198) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) ~[spring-web-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:na]
As stated on the spring.io blog regarding the Spring 4.1 release:
JSONP is now supported with Jackson. For response body methods declare
an #ControllerAdvice as shown below. For View-based rendering simply
configure the JSONP query parameter name(s) on
MappingJackson2JsonView.
#ControllerAdvice
private static class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
super("callback");
}
}
[...] In 4.1 an #ControllerAdvice can also implement
ResponseBodyAdvice in which case it will be called after the
controller method returns but before the response is written and
therefore committed. This has a number of useful applications with
#JsonView the JSONP already serving as two examples built on it.
Javadoc taken from MappingJackson2JsonView:
Set JSONP request parameter names. Each time a request has one of those
parameters, the resulting JSON will be wrapped into a function named as
specified by the JSONP request parameter value.
The parameter names configured by default are "jsonp" and "callback".
You don't need to implement this stuff by yourself. Just reuse the bits from the Spring Framework.
Spring Boot example
Following simple Spring Boot application demonstrates use of build in JSONP support in Spring MVC 4.1.
Example requires at least Spring Boot 1.2.0.RC1.
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
import java.util.Collections;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
#RestController
#SpringBootApplication
class Application {
#JsonAutoDetect(fieldVisibility = ANY)
static class MyBean {
String attr = "demo";
}
#ControllerAdvice
static class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
super("callback");
}
}
#Bean
public HttpMessageConverters customConverters() {
return new HttpMessageConverters(false, Collections.<HttpMessageConverter<?> >singleton(new MappingJackson2HttpMessageConverter()));
}
#RequestMapping
MyBean demo() {
return new MyBean();
}
#RequestMapping(produces = APPLICATION_JSON_VALUE)
String demo2() {
return "demo2";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
URL http://localhost:8080/demo?callback=test converts a POJO into a JSONP response:
test({"attr":"demo"});
URL http://localhost:8080/demo2?callback=test converts a String into a JSONP response:
test("demo2");
I'm bulid rest api using jax-rs. To handle authentication I'm using Interceptor. When auth failed I return WebApplicationException like:
try
{
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(policy.getUserName(), policy.getPassword()));
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
}
catch (AuthenticationServiceException | BadCredentialsException e)
{
throw new WebApplicationException(Response.Status.UNAUTHORIZED); //TODO set response status
}
but it returns startus 500 instead 401.
When i throw WebApplicationExceptions in services it return statuses that I set but in interceptor it didn't worked. How to return 401 from interceptor?
jaxrs:server config:
<jaxrs:server id="restService" address="/rest">
<jaxrs:serviceBeans>
<ref bean="serviceBean"/>
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<ref bean="securityInterceptor"/>
</jaxrs:inInterceptors>
</jaxrs:server>
<bean id="serviceBean" class="some_package.CustomerService"/>
<bean id="securityInterceptor" class="some_package.AuthenticatorInterceptor"/>
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Provider;
#Provider
public class Example implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) {
requestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
}
}
Your interceptor is called before the JAX-RS resource is called, meaning that it doesn't know about the JAX-RS setup yet.
I would use an ExceptionMapper to convert to an appropriate response, regardless of where it gets thrown from.
I have Spring SimpleFormController which currently works for POST requests.
I want to change the form submission to GET. So I changed the html form method="post" to method="get".
After the change, I want processFormSubmission method to be invoked.
However its not.
Can you please tell what I am doing wrong here?
import org.springframework.web.servlet.mvc.SimpleFormController;
public class VehicleDescController extends SimpleFormController
{
protected ModelAndView processFormSubmission(
final HttpServletRequest request, final HttpServletResponse response,
final Object command, final BindException errors) throws Exception
{
....
}
}
<bean name="/vehicleDesc.html"
class="com.xxx.VehicleDescController">
<property name="commandName" value="lotSeller"/>
<property name="commandClass" value="com.xxx.LotSeller"/>
<property name="formView" value="xxxTheBasics"/>
<property name="viewName" value="xxxVehicleDesc"/>
<property name="imageUploadViewName" value="imageUpload"/>
<property name="vixErrorView" value="xxxVIXError"/>
<property name="assignmentEntryService" ref="xxxService"/>
<property name="referenceDataService" ref="referenceDataService"/>
<property name="xxxReferenceDataService" ref="xxxReferenceDataService"/>
<property name="messageSource" ref="messageSource"/>
<property name="xxxService" ref="xxxService"/>
<property name="validator" ref="xxxEntryValidator"/>
</bean>
A simple:
#Override
protected boolean isFormSubmission(HttpServletRequest request) {
return true;
}
Will tell it to always follow the submit workflow of the controller. Obviously if there are both "Submits" and also "normal" GETs that come into this URL, you will have to examine the request and figure out the difference!
Has anyone been through this?
In the server side, in my OSGi application, I'm exporting a service. Here's the spring file code:
<!-- RMI SERVICE EXPORT -->
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="IntegrationRemoteService" />
<property name="service" ref="integrationExecutor" />
<property name="serviceInterface" value="my.package.services.IntegrationService" />
<property name="registryPort" value="$system{integration.port}" />
</bean>
<!-- INTEGRATION EXECUTOR -->
<bean id="integrationExecutor" class="my.package.engine.IntegrationServiceExecutor">
<property name="integrationServiceImpl" ref="integrationEngine" />
</bean>
My IntegrationServiceExecutor class extends the IntegrationService interface and implements the method:
public class IntegrationServiceExecutor implements IntegrationService {
...
#Override
public GenericResult dispatch(int serviceCode, AdapterHeader adapterHeader, AdapterInfo adapterInfo) {
The IntegrationService interface is defined in another component and this same component is used in my .war in the client side. In that component, I also have the implementation of the remote request called through my .war
...
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
...
public class GenericRmiFactory implements RemoteConnectionFactory {
private ProxyFactory proxyFactory;
public GenericRmiFactory(ServerTransport transport) throws ClassCastException, IllegalFormatException {
RmiServerTransport rmiTransport = (RmiServerTransport) transport;
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setLookupStubOnStartup( false );
rmiProxyFactoryBean.setCacheStub( false );
rmiProxyFactoryBean.setRefreshStubOnConnectFailure( true );
rmiProxyFactoryBean.setServiceUrl(String.format("rmi://%s:%s/%s", rmiTransport.getHostname(), rmiTransport.getPort(), rmiTransport.getServiceName() ));
rmiProxyFactoryBean.setServiceInterface(rmiTransport.getRemoteInterface());
rmiProxyFactoryBean.afterPropertiesSet();
this.proxyFactory = new ProxyFactory(rmiTransport.getRemoteInterface(), rmiProxyFactoryBean);
}
private ProxyFactory getproxyFactory() {
return proxyFactory;
}
#Override
public Object getRemoteService() {
return getproxyFactory().getProxy();
}
}
I call the remote service in this way:
...
IntegrationService integrationService = (IntegrationService) getGenericRemoteFactory().getRemoteService();
integrationService.dispatch(myInt, myAdapterHeader, myAdapterInfo);
...
This last statement throws the exception:
Invocation of method [public abstract my.package.result.GenericResult my.package.services.IntegrationService.dispatch(int,my.package.beans.AdapterHeader,my.package.beans.AdapterInfo)] failed in RMI service [rmi://127.0.0.1:2260/IntegrationRemoteService]; nested exception is java.lang.NoSuchMethodException: $Proxy205.dispatch(int, my.package.beans.AdapterHeader, my.package.beans.AdapterInfo)
Is there something I'm missing here?
Thanks in advance,
Karen
I've seen this before. You have to add 'throws RemoteException' to your interface method. The client throws a NoSuchMethodException, but it's really complaining about the lack of RemoteException.