AWS Flow Jar creation with Maven + Java 1.8 - maven

Has anyone been able to compile an application with Java 1.8 + AWS Flow + Maven?
I have an established Java application which has been created with Java 1.8 it uses the AWS library's and AWS flow framework. I'm looking to now automate the build of the product, I opted to use Maven. Until this point the project was exported manually within eclipse.
I have reached a point where I can build a Jar which contains our generated workflow classes ( external clients + factories ) along with what I understand to be the aspect classes ( xxxxx$1.class, xxxxx$2.class ).
The end goal is to get the weaving to happen at compile time.
However when running the maven built jar the workflows are not working as expected. The application completly ignoring the #Asynchronous annotation and results in a not ready state. As a result it will cancel the scheduling the activity we wish to execute.
I have created a simple application with a single workflow and activity to show the issues that I'm experiencing. This version has been exported via eclipse and works, but get the error shown when building via the POM.
Start with message: With Comp
Created Workers
Added implentations
Nov 28, 2016 12:14:11 PM com.amazonaws.services.simpleworkflow.flow.worker.GenericWorker start
INFO: start: GenericWorkflowWorker[super=GenericWorkflowWorker[service=com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient#163e4e87, domain=Experimental, taskListToPoll=TEST, identity=3174#ip-10-0-1-141, backoffInitialInterval=100, backoffMaximumInterval=60000, backoffCoefficient=2.0], workflowDefinitionFactoryFactory=com.amazonaws.services.simpleworkflow.flow.pojo.POJOWorkflowDefinitionFactoryFactory#56de5251]
Nov 28, 2016 12:14:12 PM com.amazonaws.services.simpleworkflow.flow.worker.GenericWorker start
INFO: start: GenericActivityWorker [super=GenericActivityWorker[service=com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient#4c60d6e9, domain=Experimental, taskListToPoll=TEST, identity=3174#ip-10-0-1-141, backoffInitialInterval=100, backoffMaximumInterval=60000, backoffCoefficient=2.0], taskExecutorThreadPoolSize=100]
Start workers
Now Sleep
Sleep Done
Make Call
DECIDER 1
DECIDER 2
DECIDER DOING CATCH
java.lang.IllegalStateException: not ready
at com.amazonaws.services.simpleworkflow.flow.core.Settable.get(Settable.java:91)
at com.amazonaws.services.simpleworkflow.flow.core.Functor.get(Functor.java:35)
at root.DeciderWFMethods.printMessage(DeciderWFMethods.java:79)
at root.DeciderWFMethods.access$100(DeciderWFMethods.java:6)
at root.DeciderWFMethods$1.doTry(DeciderWFMethods.java:54)
at --- continuation ---.(:0)
at root.DeciderWFMethods.workflowExecute(DeciderWFMethods.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.amazonaws.services.simpleworkflow.flow.pojo.POJOWorkflowDefinition.invokeMethod(POJOWorkflowDefinition.java:150)
at com.amazonaws.services.simpleworkflow.flow.pojo.POJOWorkflowDefinition.access$1(POJOWorkflowDefinition.java:148)
at com.amazonaws.services.simpleworkflow.flow.pojo.POJOWorkflowDefinition$1.doTry(POJOWorkflowDefinition.java:76)
at --- continuation ---.(:0)
at com.amazonaws.services.simpleworkflow.flow.pojo.POJOWorkflowDefinition.execute(POJOWorkflowDefinition.java:66)
at com.amazonaws.services.simpleworkflow.flow.worker.AsyncDecider$WorkflowExecuteAsyncScope.doAsync(AsyncDecider.java:70)
DECIDER DOING FINALLY
Having compared the contents of the generated jar from both eclipse and maven builds there is nothing obviously different to me.
I have searched the net for something useful but only really found example for Java 1.6 / 1.7 nothing for 1.8.
It's at this point that I should mention i'm new to maven but believe its more likely to be an AspectJ configuration / AWS build tools issue rather than Maven problem.
Build & Run
The sample application is being run on an EC2 instance using EC2 IAM roles to execute to a Workflow domain called 'Experimental'
It accepts a string which the activity upper cases, the decider should then print the message from the activity.
To build.
mvn clean
mvn package
Then running the compiled jar
java -jar Test.jar "a test message"
.
GitHub Link
https://github.com/jwhitefield-hark/aws-flow-maven
Any advice would be greatly appreciated.

We have managed to resolve this issue with help with the kind folk at the AWS forums.
Our problem were two fold.
We had compiler arguments set to -proc:none this prevented the build from completing.
Also within our aspectj-maven plugin we had set the execution to process-sources which appears to be the crux of our problem as this is preventing a good build being created and also not showing us the errors which were being generated as a result of including our compiler arguments.
As a side note within the aspectj-maven-plugin we had set the targets to 1.6 this is not required. We tried as it appeared that eclipse may have been using these setting. Either way these properties seem to have no affect.
We also changed the aspectj library from aws-java-sdk-swf-libraries to aws-swf-build-tools to keep it upto date.
https://forums.aws.amazon.com/thread.jspa?threadID=243838&tstart=0

Related

Vaadin 14 transitive NPM dependencies

I'm in the process of switching my Spring Boot + Vaadin application from Vaadin 14 in "Vaadin 13 compatibility mode" to "native Vaadin 14 mode". This is primarily because I want to use the Vaadin Gradle Plugin in order to be able to enable production mode. This also requires upgrading from Full Calendar web component to Full Calendar 4 web component, which now supports Vaadin 14+ and also wraps a newer version of FullCalendar. So lots of things needing to happen at the same time unfortunately.
The issue I'm now having, is that when the FullCalendar component is shown, I get this client-side error:
(ReferenceError) : moment is not defined
I see that the FullCalendar web component jar has these annotations on the FullCalendar class in the org.vaadin.stefan.fullcalendar package:
#NpmPackage(value = "moment", version = "2.24.0")
#NpmPackage(value = "moment-timezone", version = "0.5.28")
#NpmPackage(value = "#fullcalendar/moment", version = "4.4.0")
#NpmPackage(value = "#fullcalendar/moment-timezone", version = "4.4.0")
The reason that the first two are listed here is probably because they are defined as peer dependencies of the last two, so they are not installed automatically.
I also noticed that the FullCalendar 4 web component page mentions the following known issue:
Build problems / JS (client side) errors (V14+)
It might be, that the transitive dependencies are not resolved correctly.
If you are using Spring Boot please add the #EnableVaadin annotation to your application class. Add the package org.vaadin.stefan plus your root package as parameters. This should enable Spring to analyze all npm dependencies at runtime. Other CDI version should work the same.
So I've added this annotation to my application class:
#SpringBootApplication
#EnableVaadin({"org.vaadin.stefan", "com.mypackage"})
public class MyApplication {
But this doesn't seem to work.
I've also tried running the gradle task vaadinBuildFrontend instead of just vaadinPrepareFrontend, but that didn't make a difference.
What else should I do to make sure moment is loaded and initialized properly?
UPDATE: if I explicitly enable vaadin.productionMode in build.gradle, then the error is gone. Of course, I want to be able to run the application in development mode as well.
UPDATE 2: I've experimented with creating a clean Vaadin + Spring Boot + Gradle project from the provided base project. I noticed one difference: in my own application I get a warning logged:
dev-updater : Couldn't find dev dependencies file. Dev dependencies won't be locked
... which I don't get in the clean project. I get the following logging lines there which I don't get in my own project:
dev-updater : Visited 88 classes. Took 16 ms.
dev-updater : Skipping `pnpm install` because the frontend packages are already installed...
dev-updater : Copying frontend resources from jar files ...
dev-updater : Visited 13 resources. Took 84 ms.```
UDPATE 3: I found out that the moment() function is actually called from code that is executed using calendar.getElement().executeJs(...). Apparently the function is not known in that scope. Maybe due to strict mode? Not sure if that explains why it works in production mode.
I haven't used gradle with V14, so I cannot tell for sure, if it is maybe a gradle related reason or a Vaadin / addon issue. I just can tell, that I at least tried to setup a new project last week with the addon and it worked out of the box, so I assume, there are some tricky details burried somewhere.
Let's start with some usual question:
I assume, you use V14.3.x?
Has the moments library been downloaded (see project root > node_modules/moment and ./moment-timezone)? If not, is it listed in the package.json file?
Have you encountered this problem also with the clean Vaadin project?
And, not that I ask you to use it instead, but just for test purposes - have you tried the same setup with maven instead of gradle?
How are you using the calendar in Java. Can you show some example code of the implementation?
I was able to work around the issue because moment was used to create a parseable date string, but (at least the current version of) the library supports the ISO format returned by LocalDate#toString.
As I suspected, due to strict mode, the variable is not declared in global scope and therefore can't be used in executeJs. If it is necessary to do so, one needs to create a javascript file that adds the variable to window, and import that file using #JsModule. Then the variable in the window object can be used from executeJs.
See https://vaadin.com/forum/thread/17832455/how-to-use-external-javascript-libraries-correct-in-vaadin-14-npm and https://vaadin.com/forum/thread/17753553/can-t-use-frontend-js-with-vaadin-14.

optaplanner with aws lambda

I am using optaplanner to solve a scheduling problem. I want to invoke the scheduling code from AWS Lambda (i know that Lambda's max execution time is 5 minutes and thats okay for this application)
To achieve this I have build a maven project with two modules:
module-1: scheduling optimization code
module-2: aws lambda handler ( calls scheduling code from module-1)
When i run my tests in IntelliJ Idea for module-1(that has optaplanner code), it runs fine.
When I invoke the lambda function, i get following exception:
java.lang.ExceptionInInitializerError:
java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
at org.kie.api.internal.utils.ServiceRegistry.getInstance(ServiceRegistry.java:27)
...
Caused by: java.lang.RuntimeException: Child services [org.kie.api.internal.assembler.KieAssemblers] have no parent
at org.kie.api.internal.utils.ServiceDiscoveryImpl.buildMap(ServiceDiscoveryImpl.java:191)
at org.kie.api.internal.utils.ServiceDiscoveryImpl.getServices(ServiceDiscoveryImpl.java:97)
...
I have included following dependency in maven file: org.optaplanner optaplanner-core 7.7.0.Final
Also checked that jar file have drools-core, kie-api, kei-internal, drools-compiler. Does anyone know what might be the issue?
Sounds like a bug in drools when running in a restricted environment such as AWS-lambda. Please create a JIRA and link it here.
I was getting the same error attempting to run a fat jar containing an example OptaPlanner project. A little debugging revealed that the problem was services was empty when ServiceDiscoveryImpl::buildMap was invoked; I was using the first META-INF/kie.conf in the build, and as a result services were missing from that file. Naturally your tests would work properly because the class path would contain all of the dependencies (that is, several distinct META-INF/kie.conf files), and not the assembly you were attempting to execute on the lambda.
Concatenating those files instead (using an appropriate merge strategy in assembly) fixes the problem and appears appropriate given how those are loaded by ServiceDiscoveryImpl. The updated JAR runs properly as an AWS lambda.
Note: I was using the default scoreDrl from the v7.12.0.Final Cloud Balancing example.

Running jacoco report where integration tests are in one code base and source code is in another code base

I recently started working on creating jacoco reports for maven projects including unit and integration tests and they seem to work out correctly.
Now I have encountered a different scenario which I am not sure how to approach.
I have one workspace which consists of integration test cases - application A, but the source code does not exist in the same workspace/code base. The source code which actually runs on invoking these integration test scripts are in a different workspace/code base - application B(they are invoked using rest api calls with the localhost urls. The jboss server is started for application B so that the localhost context is up) from the integration tests.
The aim is to invoke these integration tests from application A, which in turn calls the source code of these tests in application B generating the jacoco report of the code coverage for application B.
I am not actually sure how to achieve this.
Can someone provide some input.
Thanks.
If I understand you correctly, you actually have 2 different processes in your scenario:
The "client" process that runs the integration tests and for which jacoco can be easily applied, but it's not what you need
The "server" process that runs the actual JBoss server and executes the actual code.
Client process contacts the server via HTTP.
In this case, I'm afraid jacoco won't be able to provide a coverage for you if you're running the tests from maven/gradle, because jacoco instruments only bytecode on the running JVM. So you have to be "creative" here :)
I'll list here some possible approaches
Disclaimer: I haven't tried them though (didn't work with jboss/java ee), but maybe you'll be able to at least borrow some ideas
The first approach would be running the tests together with the application somehow, like its done for example in spring tests (I'm not sure whether JBoss provides similar capabilities).
The idea is simple:
You run the integration test, it runs the jboss "embedded in the same jvm" and you can inject beans / EJB session beans into the test (like autowiring with spring).
The advantage of such a method is that you'll be able just to use jacoco maven plugin and it will instrument everything for you
I don't know how easy will be achieving this architecture technically, I know that recent jboss versions support embedded mode, So maybe you'll find This link to be a useful foundation
Another direction is to take a look at Arquillian project. They have some jacoco extension that probably will help, but I've never tried it.
And the last approach I can think of is running the jboss server with jacoco agent directly instead of relying on the build system that runs jacoco for you.
The idea here is to stream the results of covered server code into some file / tcp endpoint. So you run the jboss with -javaagent:[yourpath/]jacocoagent.jar and it starts streaming the results wherever you need it to stream. After the tests you should gather these results and prepare a report. You can find Here more information about this approach

Gradle - Compile submodules in parallel

I have a project with two sub modules.
Client - A UI based on Google's web developer kit
Server - A spring boot based server.
Now in my Gradle config(build file) on server, Im creating a jar file from the client and then including it on the server through the below snippet. Lastly, I create a .war file based on the server config.
dependencies {
compile project(':client')
}
The architecture is similar to Spring Boot's proposed ways of resource handling.
Now, when I run the Gradle build, because server is dependent on the client, the server compilation doesnt start until the client compilation and tests are done.
I feel that I'm not making use of Gradle's parallelism with this way of compiling client and server.
Are there any ways such that a compile and run test cases in parallel and then create a .war file only when both submodule's tasks are complete? How do i access the configurations of the client and server modules and then create a new war file on the rootProject?
You can try to add flag --parallel to your Gradle command. However this is still incubating feature. I noticed significant improvement on building time when running Gradle daemon, so you can try it out as well.
No, this level of parallelism is not currently available. I think the team are slowly working towards general parallel task execution, as described in their spec. That should allow for the kind of behaviour you're requesting.
That said, you can run tests in parallel if they're independent, via the maxParallelForks and forkEvery options. MrHaki gives a short how-to for this on his blog. Note that this only applies to a single Test task instance.

Using Google App Engine modules for multi-thread backend update of a Cloud endpoints project

I'm building "read-only" webservice (Google Cloud Endpoints as backend for an Android App) so I created a project using maven:
mvn archetype:generate -Dappengine-version=1.9.10 -Dfilter=com.google.appengine.archetypes:
and selecting archetype hello-endpoints-archetype to have some sample code to work on.
This works well and my app is correctly calling the service as expected (and the service is correctly supplying the data in return).
Now I have to implement an "update" service to periodically (4 to 6 times a dya) update the data supplied to the app. So I added a servlet to my project to be called by cron. Trouble is: one of the library used during this update uses multi-threads which cause an AccessControlException to be thrown because apparently multi-thread is only allowed in backend modules...
But after having read dozens of pages on google app engine, I still don't know how to "break" my application into modules so that particular servlet would be run as a backend module while the already existing servlet keep working as they do. So far, all I got was that I should use an EAR application composed of several WAR modules, but I don't even know if my current application is an EAR or not...
I'm using Eclipse Luna, maven 3.2.1 (embeded with Eclipse), google app engine 1.9.10, writing in Java
Could anyone please help me by explaining the directory structure and/or configuration files I have to look at, modify and/or add?
Thanks for any help provided!
You can find an example of multi-modules project here.
However, note that even in backend modules the threading is limited to 50 threads, as stated here.

Resources