Combining Akka, Spray, and embedded Jetty - scala

I'm trying to create a standalone JAR containing Akka, Spray, and Jetty. Ideally I distribute the entire application in that single file, without any external files whatsoever.
I understand how to create an embedded Jetty server instance
def main(args: Array[String]): Unit = {
val server = new Server(9012);
server.start();
server.join();
Thread.sleep(2000);
server.stop();
}
and I've followed the Spray example code in creating a HelloService and Boot class, but I have no earthly idea of how to connect the two, so that when a URL is requested on the Jetty server a Spray service responds to it. Any help would be much appreciated.
Update: I'm getting a lot closer to solving this problem, thanks to a thread of inquiry prompted by Alois Cochard (I'm coming from a web scripting background, and getting my head around Java web services has been ... challenging!). I've modified my main method to start the server and read the Jetty and akka configuration files that are in the getting started template. It's reading both of those files, but now I'm getting this when I navigate to / on the Jetty server:
HTTP ERROR: 500
Problem accessing /. Reason:
assertion failed: 0 actors for id 'spray-root-service' found, expected exactly one
I know I'm missing something silly (and probably that I should break down and use SBT, but being able to just compile and run in Eclipse, and then refresh in the browser, is so simple and appealing).
Update #2: Figured out the problem. I wasn't creating a WebAppContext object, which meant that the web.xml was never getting read, and thus Akka was never being loaded. This is the revised main method which is now working.

According to the spray-template, you should add the Spray servlet connector in the web.xml configuration file:
http://github.com/spray/spray-template/blob/master/src/main/webapp/WEB-INF/web.xml
You can find some informations about how to configure a standealone jetty to use this file here (there is surely better references in netty documentation directly):
http://exist.sourceforge.net/deployment.html#d47e594
BTW, using the spray template as a basis for your project looks like a good idea ;)

Related

vertx build with graalvm

I fallowed https://github.com/vertx-howtos/graal-native-image-howto/blob/20.3.0/README.adoc and manage to build my vertx project with graalvm, but when I start the native image vertx is not starting. I can not see vertx logs, "listening on..."
You can see my full pom here
And java code here
Adding some error handling to the application will show that the 1st problem is related to missing the file application.properties from the image, this can be fixed by updating the native-image.properties config with:
-H:IncludeResources=.*\\.properties
Then the application will start but again will fail to return data. This is because the application is using jackson databind (which relies on reflection) to encode the POJO to JSON.
Fixing it requires some understanding on how jackson reflection works and write the correct configuration, or just keep it simple and use Vert.x built in JSON types, for example:
req.response()
.putHeader("content-type", "application/json")
.end(new JsonObject()
.put("name", "vertx")
.put("releaseYear", LocalDate.now().getYear())
.encode());

Apache Felix not binding my configuration correctly - wrong inputstream version

I had a bundle deployed in an Apache Felix (Sling, in fact) host. The bundle contained some configurable elements, and its version was 2.0.
I have updated the bundle to v2.0.1 for some small code changes, and now the bundle will not pick up its configuration correctly - it remains at the defaults set in code rather than picking up the values configured in the Felix Web Console.
There is an error message in the log: "[Configuration Updater] org.apache.felix.scr Cannot use configuration pid=com.mypackage.MyClass for bundle inputstream:my-bundle-2.0.1.jar because it belongs to bundle inputstream:my-bundle-1.0.jar" which sounds like the cause of the issue.
However:
I can't edit the inputstream value through the web interface - only by stopping the server, editing the config file manually, and restarting. Surely when I update the bundle, the config should be updated too?
Although the inputstream specifies v1.0, the bundle did not have a problem when it was upgraded to v2.0. What's made the difference here?
I have done the same thing (though perhaps not exactly!) on two servers, and one server seems to have the config specify inputstream=v2.0 (and the bundle at v2.0.1) and it works fine. What caused inputstream version to update on this server? (Presumably the same as the answer to 2 - I imagine it'll depend exactly which steps in the process have been executed and in what order.)
Any advice gratefully received - I haven't been able to find any documentation that gives instructions or troubleshooting suggestions for administering bundles through the Felix Web Console.
If at all possible, I would simply stop and remove the bundle altogether and install it using Sling , e.g. with the maven-sling-plugin or dropping it in the /apps/myapp/install folder using WebDAV .
I find it easiest to be consistent this way and the installation is nicely automated and it handles bundle upgrades properly.

java.lang.NoSuchFieldError returns when trying to create a stateless session to the Rules Execution Server

I am using Ilog JRules Studio 7.1.1 for the rules development. I am using JUnit test cases to test the developed rules.
When i am trying to create a stateless session to the RES, it's returning with the below error.
IlrStatelessSession session = factory.createStatelessSession();
Anyone is having any idea?
java.lang.NoSuchFieldError: ilog/rules/res/decisionservice/plugin/IlrWsdlGenerationInteractionSpec.FUNCTION_NAME_BACKPORT_GENERATE_WSDL
at ilog.rules.res.decisionservice.plugin.IlrWsdlGeneratorInteractionExtension.getSupportedFunctionNames(IlrWsdlGeneratorInteractionExtension.java:418)
at ilog.rules.res.xu.plugin.impl.IlrPluginManager.createPlugins(IlrPluginManager.java:222)
at ilog.rules.res.xu.plugin.impl.IlrPluginManager.changePlugins(IlrPluginManager.java:173)
at ilog.rules.res.xu.plugin.impl.IlrPluginManager.start(IlrPluginManager.java:135)
at ilog.rules.res.xu.spi.IlrManagedXUConnectionFactory.createConnectionFactory(IlrManagedXUConnectionFactory.java:648)
at ilog.rules.res.xu.spi.IlrManagedXUConnectionFactory.createConnectionFactory(IlrManagedXUConnectionFactory.java:668)
at ilog.rules.res.session.util.IlrJ2SEConnectionFactoryFinder.findConnectionFactory(IlrJ2SEConnectionFactoryFinder.java:23)
at ilog.rules.res.session.IlrJ2SESessionFactory.createClientFactory(IlrJ2SESessionFactory.java:93)
at ilog.rules.res.session.IlrJ2SESessionFactory.getClientFactory(IlrJ2SESessionFactory.java:129)
at ilog.rules.res.session.IlrJ2SESessionFactory.createStatelessSession(IlrJ2SESessionFactory.java:62)
Regards,
Hari
Nothing to do with the session.
JRules is crashing because it is not able to generate the WSDL, meaning there is something wrong with your project at first.
Try to run it locally first.
The thing is a web service is automatically provided if the XOM is based on XSD
There is an error somewhere in your project. If you use XSD (which I guess) then have a look to your rule project.
If you use JAVA XOM then there is an error in your web service server (which I doubt) because I cannot see why JRules would complain for your own code.
Verify your in/output parameters
Make it simple first then complicate the process.If simple then redeploy...
Hope it helps

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.

GWT logging to file

I am writing my first GWT and i confess i have no idea how to set up loggers.
I am deploying the application to tomcat and want to be able to set up a logger so that i can log to a file in $catalina.home. Gwt came with logging.properties for a java util style log and log4j.properties; i have looked at documentation for the gwt java util logger and it seems to just write to console so it must be log4j i need?
In the past ive seen org.apache.log4j.Logger used, is this what i want?
Could somebody please point me to somewhere where this is documented?
Thanks.
The documentation is here. You can't use file appenders directly because the GWT code runs as Javascript in the browser (when not in development mode). If you want to log to a file you need to enable remote logging.
If there is a server side part logging works as normal. But then it has not much to do with GWT, except for being in the same project and providing services (via a custom protocol).
What do you want to log? rpc service servlets or client logic?
Log4j is just for java not javascript. So it is intended to log your classes in your /server/ package that will be deployed in your server.
Your /client/ package classes will be translated to javascript and will run in the client browser. So, no Java at all!
You can use log4j "emulated" to javascript with http://code.google.com/p/gwt-log/ which will send your client logs using a RemoteLogger to the server via rpc and then you can log them to a file.