Eclipse 4 declarative service injection in a declarative service - eclipse

I am creating declarative services, lets call them Service1 and Service2.
Everything works fine in my eclipse RCP application.
Now I want my Service1 to be injected into Service2, so my Service2 class have a new field like this :
#Inject
Service1 myService1;
This never gets injected and Debugging a little the Declarative Service instanciation in Eclipse 4 (org.eclipse.equinox.internal.ds.model.ServiceComponent) it seems that nothing get injected after the class has been instanciated.
Is this a limitation of the DS implementation in eclipse ?
Is there a way to fix this ?
Thanks.

No, it is not possible by default. You can make some utility class which is called on #Acivate which searching the coresponding service on tracker and sets the #Inject service with reflection, but in that case you will lose all of lifecycle, so its not a nice osgi way.
If you would line to use #Inject annotation you can use pax-cdi for that, but on that case you cannot use the declarative service annotations on that class - because in that case the pax will instantiate and register the service on the tracker.

Related

Eclipse Scout Neon : service registry does not contain a service of type

I try to call scout service from Scout Form, so I create interface in shared folder
#TunnelToServer
public interface IPersonsFormService extends IService {
void test();
}
and in server I created implementation of this interface
public class PersonsFormService implements IPersonsFormService {
#Override
public void test() {
System.out.println("TEST");
}
}
but I get
o.e.scout.rt.platform.exception.ExceptionHandler - SecurityException:service registry does not contain a service of type com.sixt.leasing.contract.scout.shared.person.IPersonsFormService [majorPrincipal: 'marko']
java.lang.SecurityException: service registry does not contain a service of type com.sixt.leasing.contract.scout.shared.person.IPersonsFormService
It looks like interface is not registered, but in Neon I thought that service is registered with #TunnelToServer annotation.
Where else should I register service ?
This project is extension project of main project.
In Main project all services works,....
Solution: put scout.xml with default content in src/main/resources/META-INF folder of the server project.
Why did this happen? Since this is an extension we apparently forgot to copy this file and Scout Neon seems to ignore projects that don't contain this file.
Figured this out by putting a PlatformListener in that project and since that never triggered it was easier to track down the issue.
This annotation is requested for Remote-Service (see also the 3.5.1. #TunnelToServer section). The implementation class (or the interface) should have the #ApplicationScoped annotation.
For Local-Service, use either the #Bean or the #ApplicationScoped annotation to register the service.
If your annotations are correct, your Jandex index might be broken.
Start the application with -Djandex.rebuild=true to rebuild the application on startup.
This will recalculate each of your target/classes/META-INF/jandex.idx files.
Of course, you can also delete each file manually. Running mvn clean also clean those files.

Missing NamedQueries annotation in WAS Liberty environment

I'm using WAS Liberty 8.5.5.5 under Java 7 (tried under Oracle java 7-8 and IBM java 7 as well).
When I create one NamedQuery, the code compiles, deployes, and runs fine.
However, If I try to use the NamedQueries annotation I get the following excpetion:
java.lang.ArrayStoreException: com.sun.proxy.$Proxy29
at sun.reflect.annotation.AnnotationParser.parseAnnotationArray(AnnotationParser.java:765)
at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:537)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.Class.createAnnotationData(Class.java:3521)
at java.lang.Class.annotationData(Class.java:3510)
at java.lang.Class.getAnnotation(Class.java:3415)
After some investigation, I found the following two bugs:
ArrayStoreException in Jboss: https://issues.jboss.org/browse/JBAS-9392
ArrayStoreException when annotation declaring class missing: http://bugs.java.com/view_bug.do?bug_id=7183985
It seems that the javax.persistence.NamedQueries inteface is missing in the enviroment (stangely the javax.persinstence.NameQuery is present ...)
I use Eclipse Kepler for development, the deployment is also handled by the IDE.
On more thing; other developers using the same code base can successfully deploy and run the application with the afformentioned settings - so I suspect the deployment might be responsible for this issue.
Is there a way to "tell" the WAS to include the missing class runtime?
It took some time, but I found the solution.
We are using Ecliselink as a JPA provider, and load it accordingly:
<classloader commonLibraryRef="EclipseLinkLib" delegation="parentLast"/>
It seems that Eclipselink (version 2.5.2) contains the javax.persistence.NamedQuery interface, but not the javax.persistence.NamedQueries interface - this way WAS does not load the missing interface.
By changing delegation="parentFirst" the app works fine.

Starting Scala application in SBT for integration test

I have a Scalatra web service that runs with embedded Jetty. I'd now like to write integration tests that:
start the service (using the main method of the application)
run the tests (driving the HTTP interface)
stop the service.
This should all be triggered by an SBT command.
How should I go about this?
You could write such integration tests on top of BDD test frameworks like Specs. Unfiltered project has many such examples that should work for other web frameworks like Scalatra.
For example, take a look at ServerSpec:
"A Server" should {
"respond to requests" in {
http(host as_str) must_== "test"
}
....
}
It's starting up a test server specified in setup and hitting it using Dispatch in the specification. The key part is implemented in unfiltered.spec.jetty.Served trait, which does that you described: starting and stopping the service. There's also Specs2 version: unfiltered.specs2.jetty.Served.
Another trick you could use is sbt-revolver, which my favorite plugin while doing any web development, especially used in conjunction with JRebel. This plugin can load your web server in the background. I haven't tried test together, but it could work if you don't have to change the server-side during the test.
Scalatra offers a DSL to write tests. There is support for specs2 and scalatest.
By default an embedded Jetty will be used for testing. If you want to provide your own server, you can reuse the EmbeddedJettyContainer implementation and override start, stop and servletContextHandler.
start will be called before executing the tests, which allows to start your server if required. stop is called after the tests. servletContextHandler is required in order to add your servlets using addServlet(..).
This is from the spec2 integration:
trait BaseScalatraSpec extends SpecificationStructure with FragmentsBuilder with ScalatraTests {
override def map(fs: =>Fragments) = Step(start()) ^ super.map(fs) ^ Step(stop())
}
trait ScalatraTests extends EmbeddedJettyContainer with HttpComponentsClient { }
Alternatively you can provide your own Container implementation.

How to share a GWT RPC RemoteServiceServlet among multiple client modules / apps

I have several GWT modules and web apps running in Jetty. They each want to use my LoginService RPC interface, so I put this interface and its servlet implementation in a common module. I serve the servlet (LoginServiceImpl) from my root web context, and web.xml exposes it at the url "/loginService". In a another GWT module, to use this service, I had to set the entry point, like this...
LoginServiceAsync loginService = GWT.create(LoginService.class);
ServiceDefTarget t = (ServiceDefTarget)loginService;
t.setServiceEntryPoint("/loginService");
Now, the module trying to use the loginService is called discussions, and I get this error on the server.
ERROR: The serialization policy file
'/discussions/discussions/7B344C69AD493C1EC707EC98FE148AA0.gwt.rpc' was not found;
did you forget to include it in this deployment?
So the servlet is reporting an error that mentions the client (the discussions module). I'm guessing that the RPC plumbing passed the name of this .rpc file through from the client, and the servlet is now looking for it. (?) As an experiment, I copied, the *.gwt.rpc files from the discussions module into the root web context, so the servlet could find them. This did stop the error. But I still get another error:
com.google.gwt.user.client.rpc.SerializationException: Type
'mystuff.web.shared.User' was not assignable to
'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field
serializer. For security purposes, this type will not be serialized.: ...
This class is serializable; it worked before in other modules, so now I'm lost.
What is the right way to use the LoginService from multiple clients modules?
Update:
This error was showing up in hosted devmode, and it went away after a full compile. Maybe this is related to gwt serialization policy hosted mode out of sync . I will update again if I can better reproduce the problem.
See my answer here. The short answer is: you'll need to make mystuff.web.shared.Users source available at compile-time to your discussions module.

How to auto execute a session bean's method on ear deployment?

I need a way to have a session bean's method executed periodically every week at a certain time. I am thinking of using the quartz scheduler to do this. My question is, how do I start the scheduler to run from the moment the .ear file is deployed automatically? Is there any annotation that I can use on the stateless session bean calling the scheduler.start method such as #PostConstruct or something?
The problem with #PostConstruct for a stateless bean is that something has to trigger the bean to be constructed.
There's no standard way to do what you're trying to do until EJB 3.1 (automatic timers or startup singleton session beans). Until then, you could use a dummy WAR with a ServletContextListener to set up your EJB timer.