I have doubt on the below code..
#RemoteServiceRelativePath("stockPrices")
public interface StockPriceService extends RemoteService {
StockPrice[] getPrices(String[] symbols);
}
Could any one explain me what is the use of #RemoteServiceRelativePath("stockPrices") and what name we need to give in "stockPrices" .. is it mandatory??
thanks in advance!!!
Check out documentation for RemoteServiceRelativePath annotation, it explains pretty well what this annotation does. In your case, your service must be located at GWT.getModuleBaseURL() + "stockPrices" ... that means that if your GWT app is at /mygwtapp, then your service must be at /mygwtapp/stockPrices. It's up to you to install some service at this URL, usually by defining servlet implementing the service interface.
You can use any other path instead of "stockPrices", just make sure there is real service behind this path on the server.
Your remote services need some remote path (entry point), either by using #RemoteServiceRelativePath annotation, or by setting it through ServiceDefTarget interface. If service has no entry point, it cannot be called. (Remember: this path is URL on the server)
For example, instead of using #RemoteServiceRelativePath, you can define your service without this annotation, and then when you instantiate async service proxy, you explicitly set path:
StockPriceServiceAsync stockService = GWT.create(StockPriceService.class);
((ServiceDefTarget) stockService).setServiceEntryPoint("/services/stock.service");
Related
I'm trying to add a RESTful web service with RESTeasy to our application running on JBoss 7.x, using Seam2.
I wanted to use as little Seam as possible, but I need it for Dependancy Injection.
My REST endpoints are as follows:
#Name("myEndpoint")
#Stateless
#Path("/path")
#Produces(MediaType.APPLICATION_JSON+"; charset=UTF-8")
public class MyEndpoint {
#In private FooService fooService;
#GET
#Path("/foo/{bar}")
public Response foobar(#CookieParam("sessionId") String sessionId,
#PathParam("bar") String bar)
{ ... }
}
I'm using a class extending Application. There is no XML config.
I can use the web service methods and they work, but I always get an IllegalStateException:
Exception processing transaction Synchronization after completion: java.lang.IllegalStateException: No event context active
Complete StackTrace
I did try everything in the documentation, but I can't get it away. If I leave out the #Stateless annotation, I don't get any Injection done. Adding #Scope doesn't do jack. Accessing the service via seam/resource/ doesn't even work (even without the Application class with #ApplicationPath).
It goes away if I don't use Dep. Injection, but instead add to each and every method
fooService = Component.getInstance("fooService");
Lifecycle.beginCall();
...
Lifecycle.endCall();
which isn't really a good solution. Nah, doesn't work either...
I have resolved the issue. For some reason (still not sure why, maybe because I tried to use Annotations and code exclusivly and no XML config), my REST service was availiable under a "non-standard" URL.
Usually it'd be something like "/seam/resources/rest".
Anyway, if you have a "custom" path, Seam doesn't know it should inject a context. You need to add <web:context-filter url-pattern="something" /> to your component.xml.
Specifically we already had this tag, but with the attribute regex-url-pattern and I extended it to match the REST URL.
I want to solve the following problem and need advice, what the best solution is.
I have a bundle A in which a service interface X is defined. A bundle B provides a service implementation of X and contributes the implementation to the tool. A and B use Google Guice and Peaberry to configure the setup of the objects.
There are two possibilities I can use to contribute the service implementation:
Using an eclipse extension:
In this solution I can use the GuiceExtensionFactory mechanism of Peaberry to create the service implementation using Guice and therefore can inject stuff needed by the implementation. The disadvantage here is that in the bundle defining the extension point, I need the boilerplate code for the resolution of the extensions because there is to my knowledge no way to get the extensions injected into the class which uses the extensions.
This looks like this:
<extension point="A.service.X">
<xservice
...
class="org.ops4j.peaberry.eclipse.GuiceExtensionFactory:B.XImpl"
.../>
</extension>
<extension
point="org.ops4j.peaberry.eclipse.modules">
<module
class="B.XModule">
</module>
</extension>
but I need the boilerplate code like this:
private List<X> getRegisteredX() {
final List<X> ximpls = new ArrayList<>();
for (final IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor( X_EXTENSION_POINT_ID)) {
try {
final Object object = e.createExecutableExtension("class"); //$NON-NLS-1$
if (object instanceof X) {
ximpls.add((X) object);
}
} catch (final CoreException ex) {
// Log
}
}
return ximpls;
}
Using an OSGI service:
My main problem here is to ensure that the service is registered. I want the bundle loaded lazily, so at least an access to one of the classes of the bundle is required. Registering the service programmatically using Peaberry has an issue, because nobody ever asks for a class of the bundle. The solution is to provide the service as a declarative service, but I do not know a way to create the service implementation in a way, that I can use Guice to inject required objects.
So I have some questions:
Is there something I do not know so far that implements the code needed to read the extensions at an extension point generically and allows to inject the extensions to the class using the extensions?
Is there a way to ensure that the service is provided even if it is added using the standard Peaberry mechanism, i.e., the bundle is activated when the service is requested?
Is there a way like the GuiceExtensionFactory for declarative services, so that the creation of the service implementation can be done by the injector of the bundle?
Something that look like:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Ximpl">
<implementation class="some.generic.guiceaware.ServiceFactory:B.Ximpl"/>
<service>
<provide interface="A.X"/>
</service>
</scr:component>
Summarized, I want a service implementation generated by Guice and I want to get the service implementations simply injected into the classes using the service without extensive boilerplate code. Has anybody a solution for that?
Sorry, to ask, but I searched the web for quite a while and so far I did not find a solution.
Thanks and best regards,
Lars
I found a solution, but since I did not find it without a lot of trying out and thinking I thought I share it here. From the options I mentioned in my posting, my solution uses the first one, that is Eclipse extension points and extensions. In order to use Guice in the context of extension points there are two aspects to consider:
Providing an extension that is created by an Guice injector
This is explained very well here: https://code.google.com/p/peaberry/wiki/GuiceExtensionFactory. There is one remark to make from my side. The creation of the extension object is done in an injector inside of the GuiceExtensionFactory, so it is an own context, which needs to be configured by the module given as additional extension to the factory. This can become an issue, if you have other needs that require creating the injector in the bundle on your own.
Defining an extension point so that the extensions are simply injected into the classes which use the extensions.
First thing to do is to define the extension point schema file as normally. It should contain the reference of an interface that has to be implemented by the extensions.
The id of the extension point has to be connected to the interface which is provided by the extensions and which is injected by guice/peaberry. Therefore peaberry provides an annotation to be used to annotate the interface:
import org.ops4j.peaberry.eclipse.ExtensionBean;
#ExtensionBean("injected.extension.point.id")
public interface InjectedInterface {
...
}
On some web pages you also find the information that if the id is equal to the qualified name of the interface, it can be found directly without the annotation but I did not try this out.
In order to enable the injection, you have to do two things to configure the Guice injector creation.
First the EclipseRegistry object of Peaberry has to be set as ServiceRegistry. Second the binding of the extension implementations to a provided service has to be done.
The injector creation has to be done in this way:
import org.osgi.framework.BundleContext;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.ops4j.peaberry.eclipse.EclipseRegistry;
import static org.ops4j.peaberry.Peaberry.*;
void initializer() {
Injector injector = Guice.createInjector(osgiModule(context, EclipseRegistry.eclipseRegistry()), new Module() {
binder.bind(iterable(InjectedInterface.class)).toProvider(service(InjectedInterface.class).multiple());
});
}
The extension implementations can then simply be injected like this:
private Iterable<InjectedInterface> registeredExtensions;
#Inject
void setSolvers(final Iterable<InjectedInterface> extensions) {
registeredExtensions = extensions;
}
With the described way it is possible to have injected extensions which are implemented by classes using Guice to get dependencies injected.
I did not find a solution to use osgi services so far, but perhaps there is someone who has an idea.
Best regards,
Lars
I have a domain class called StoreType.java which is exposed by below spring repository
public interface StoreTypeRepository extends PagingAndSortingRepository<StoreType, Short> {
}
When I access this using url http://localhost:8080/my-persistence/jpa/storetypes it returns 404.
if I change my domain class as Storetype (without camel case), it works fine and return 200 OK.
I have few more repositories which uses single world domain classes like Store.java , Country.java and these work fine and by default these exposed as plural of domain class name.
I know spring exposed url as plural of domain classes but not sure why it is not exposing it. I can override this using #RepositoryRestResource(path="/storetypes") but I want to know what is default rest url if domain classes name in camel case.
You seem to have answered the question to your problem by specifying the #RepositoryRestResource( path="/storetypes" ) annotation as the documentation states.
Spring Data REST exposes a collection resource named after the uncapitalized, pluralized version of the domain class the exported repository is handling. Both the name of the resource and the path can be customized using the #RepositoryRestResource on the repository interface.
In this case your naming convention seems correct using StoreTypeRepository however one thing confuses me about your repository definition... I'm not sure why you set the type parameter to the PagingAndSortingRepository<StoreType, Short> but I'm quite certain that's incorrect as the second type parameter should be of type Long.
In Java EE I notice that you can specify a path to a uri either as
#Path("/SomePath")
public class MyClass
or
#WebServlet("/SomePath")
public class MyClass extends HttpServlet
I think #Path is used for non-servlet stuff while #WebServlet is used for servlets. But do they effectively serve the same purpose?
Info on #Path can be found here:
http://docs.oracle.com/cd/E19798-01/821-1841/6nmq2cp26/index.html
But at first glance, it seems to provide some of the basic functionality as #WebServlet.
#Path annotation defines a path to a RESTful Web service so when you have #Path("/SomeService") it will translate into www.yourapp.com/baseRestUrl/SomeService. You can also define it on the methods which provides REST services. Note that baseRestUrl is defined inside web.xml or in class which extends Application class.
On the other hand #WebServlet("/SomePath") states that Servlet will be listening for request on the www.yourapp.com/SomePath, it is basically replacement of servlet-mapping element in web.xml. You can still configure servlets like this, it's up to you whether you prefer XML or annotation configuration.
The #Path annotation identifies the URI path template to which the resource responds and is specified at the class or method level of a resource. The #Path annotation’s value is a partial URI path template relative to the base URI of the server on which the resource is deployed, the context root of the application, and the URL pattern to which the JAX-RS runtime responds.
The #WebServlet annotation is used to declare a servlet. The annotated class must extend the javax.servlet.http.HttpServlet class.
I got a JAXRS application. I have an Interface class (SomeResource) (where i put most of my annotations) and an implementation of this interface (SomeService).
I have registered the SomeService.class in the overriden JaxRSApplication method .getClasses();
All my other services/resources are implemented in the same way, but whenever i try to call this one service (SomeService), i get the following exception:
"Error 500: javax.servlet.ServletException: java.lang.IllegalAccessException: Class org.apache.wink.server.internal.handlers.InvokeMethodHandler can not access a member of class package.api.SomeResource with modifiers "public abstract""
As you can see, for some reason, this one Service tries to call the Resource(Interface) instead of the the Service class with the actual implementation.
Anyone got an idea how to resolve this? (Real classnames hidden because of security).
Be sure to declare the implementation class of the service (SomeService.class) with its full qualified classname and not the interface within your rest service configurationen of your application.
The way you have to do that depends on the implementing framework.
Have a look here:
http://cxf.apache.org/docs/jaxrs-services-configuration.html