This is an automated email from the ASF dual-hosted git repository.

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans-meecrowave.git


The following commit(s) were added to refs/heads/master by this push:
     new 2c4ac61  basic graal integration - pre-arthur-knight
2c4ac61 is described below

commit 2c4ac6113fb318c3eff78f0af2ae5b4d57833b8d
Author: Romain Manni-Bucau <rmannibu...@gmail.com>
AuthorDate: Wed Mar 17 18:31:40 2021 +0100

    basic graal integration - pre-arthur-knight
---
 meecrowave-doc/src/main/jbake/content/howto.adoc | 416 +++++++++++++++++++++++
 1 file changed, 416 insertions(+)

diff --git a/meecrowave-doc/src/main/jbake/content/howto.adoc 
b/meecrowave-doc/src/main/jbake/content/howto.adoc
index 11c9285..6727668 100755
--- a/meecrowave-doc/src/main/jbake/content/howto.adoc
+++ b/meecrowave-doc/src/main/jbake/content/howto.adoc
@@ -306,3 +306,419 @@ You should add a <webapp> element to the meecrowave 
plugin configuration. Exampl
 will add the content of the "dist" folder to your package and its files will 
be available on the application root.
 
 Note that your frontend will be served when executing the app (on a mvn 
meecrowave:run or when running a packaged app). It will not be available during 
unit tests.
+
+== How to compile a Meecrowave application with GraalVM
+
+You can use `native-image` directly but for this how to, we will use 
link:http://geronimo.apache.org/arthur/[Apache Arthur] which enables to do it 
through Apache Maven.
+The trick is to define the Tomcat and Meecrowave resources to use to convert 
the Java application in a native binary.
+For a simple application here is how it can be done.
+
+TIP: we use link:https://yupiik.github.io/yupiik-logging/[Yupiik Logging] in 
this sample to replace Log4j2 which is not GraalVM friendly, this JUL 
implementation enables runtime configuration even for Graalified binaries.
+
+[source,xml]
+----
+<plugin> <!-- mvn -Parthur arthur:native-image@runtime -e -->
+  <groupId>org.apache.geronimo.arthur</groupId>
+  <artifactId>arthur-maven-plugin</artifactId>
+  <version>${arthur.version}</version> <!-- >= 1.0.3 or replace openwebbeans 
extension by openwebbeans 2.0.22 dep + openwebbeans-knight with arthur v1.0.2 
-->
+  <executions>
+    <execution>
+      <id>graalify</id>
+      <phase>package</phase>
+      <goals>
+        <goal>native-image</goal>
+      </goals>
+    </execution>
+  </executions>
+  <configuration>
+    <graalVersion>21.0.0.2.r11</graalVersion> <!-- use this graal version 
(java 11 here) -->
+    <main>org.apache.meecrowave.runner.Cli</main> <!-- set up meecrowave 
default main - requires commons-cli -->
+    <buildStaticImage>false</buildStaticImage> <!-- up to you but using arthur 
docker goals it works fine and avoids some graalvm bugs -->
+    <usePackagedArtifact>true</usePackagedArtifact> <!-- optional but enables 
a more deterministic run generally -->
+    <graalExtensions> <!-- enable CDI -->
+      <graalExtension>openwebbeans</graalExtension>
+    </graalExtensions>
+    <reflections> <!-- enable cxf/owb/tomcat main reflection points  -->
+      <reflection> <!-- used by meecrowave to test cxf presence -->
+        <name>org.apache.cxf.BusFactory</name>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.core.UriInfo</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.core.HttpHeaders</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.core.Request</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.core.SecurityContext</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.ext.Providers</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.ext.ContextResolver</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.servlet.http.HttpServletRequest</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.servlet.http.HttpServletResponse</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>javax.ws.rs.core.Application</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- meecrowave registers it programmatically -->
+        <name>org.apache.meecrowave.cxf.JAXRSFieldInjectionInterceptor</name>
+        <allPublicConstructors>true</allPublicConstructors>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.CXFBusLifeCycleManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.ClientLifeCycleManagerImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.EndpointResolverRegistryImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.HeaderManagerImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.PhaseManagerImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.ServerLifeCycleManagerImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.ServerRegistryImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.managers.WorkQueueManagerImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.bus.resource.ResourceManagerImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.catalog.OASISCatalogManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.common.spi.ClassLoaderProxyService</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.common.util.ASMHelperImpl</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.service.factory.FactoryBeanListenerManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.transport.http.HTTPTransportFactory</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.catalog.OASISCatalogManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.endpoint.ClientLifeCycleManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.buslifecycle.BusLifeCycleManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.phase.PhaseManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.resource.ResourceManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.headers.HeaderManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.common.util.ASMHelper</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.common.spi.ClassLoaderService</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.endpoint.EndpointResolverRegistry</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.endpoint.ServerLifeCycleManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.workqueue.WorkQueueManager</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- CXF SPI -->
+        <name>org.apache.cxf.endpoint.ServerRegistry</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection>
+        <name>org.apache.cxf.cdi.DefaultApplication</name>
+        <allPublicConstructors>true</allPublicConstructors>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>org.apache.cxf.transport.http.Headers</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection>
+        <name>org.apache.cxf.jaxrs.JAXRSBindingFactory</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- used by cxf-cdi to test owb-web presence -->
+        <name>org.apache.webbeans.web.lifecycle.WebContainerLifecycle</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- instantiated by a SPI -->
+        <name>org.apache.meecrowave.logging.tomcat.LogFacade</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- for default binding since meecrowave uses a filter for 
jaxrs -->
+        <name>org.apache.catalina.servlets.DefaultServlet</name>
+        <allPublicConstructors>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- tomcat does reflection on it -->
+        <name>org.apache.catalina.loader.WebappClassLoader</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- tomcat does reflection on it -->
+        <name>org.apache.tomcat.util.descriptor.web.WebXml</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- tomcat does reflection on it -->
+        <name>org.apache.coyote.http11.Http11NioProtocol</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- tomcat instantiates it by reflection -->
+        <name>org.apache.catalina.authenticator.NonLoginAuthenticator</name>
+        <allPublicConstructors>true</allPublicConstructors>
+      </reflection>
+      <reflection> <!-- should be all API a proxy can be created for -->
+        <name>javax.servlet.ServletContext</name>
+        <allPublicMethods>true</allPublicMethods>
+      </reflection>
+      <reflection> <!-- used by meecrowave integration -->
+        <name>org.apache.cxf.jaxrs.provider.ProviderFactory</name>
+        <methods>
+          <method>
+            <name>getReadersWriters</name>
+          </method>
+        </methods>
+      </reflection>
+      <reflection> <!-- used by meecrowave integration -->
+        
<name>org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider$ProvidedInstance</name>
+        <fields>
+          <field>
+            <name>instance</name>
+          </field>
+        </fields>
+      </reflection>
+      <reflection>
+        <name>org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider</name>
+        <fields>
+          <field>
+            <name>providers</name>
+          </field>
+        </fields>
+      </reflection>
+      <reflection> <!-- not needed with arthur 1.0.3 -->
+        <name>org.apache.xbean.finder.AnnotationFinder</name>
+        <fields>
+          <field>
+            <name>linking</name>
+            <allowWrite>true</allowWrite>
+          </field>
+        </fields>
+      </reflection>
+    </reflections>
+    <resources> <!-- register tomcat resources and optionally default 
meecrowave app configuration -->
+      <resource>
+        <pattern>org\/apache\/catalina\/.*\.properties</pattern>
+      </resource>
+      <resource>
+        <pattern>javax\/servlet\/(jsp\/)?resources\/.*\.(xsd|dtd)</pattern>
+      </resource>
+      <resource>
+        <pattern>meecrowave\.properties</pattern>
+      </resource>
+      <resource>
+        <pattern>META-INF/cxf/bus-extensions\.txt</pattern>
+      </resource>
+      <resource>
+        <pattern>org/apache/cxf/version/version\.properties</pattern>
+      </resource>
+    </resources>
+    <includeResourceBundles>
+      <includeResourceBundle>org.apache.cxf.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.interceptor.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.bus.managers.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.jaxrs.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.jaxrs.provider.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.jaxrs.interceptor.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.jaxrs.utils.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.cxf.transport.servlet.Messages</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.authenticator.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.connector.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.core.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.deploy.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.filters.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.loader.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.manager.host.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.manager.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.mapper.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.realm.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.security.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.servlets.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.session.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.startup.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.users.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.util.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.valves.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.valves.rewrite.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.catalina.webresources.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.coyote.http11.filters.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.coyote.http11.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.coyote.http11.upgrade.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.coyote.http2.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.coyote.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.buf.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.codec.binary.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.compat.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.descriptor.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.descriptor.tld.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.descriptor.web.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.digester.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.http.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.http.parser.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.json.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.modeler.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.net.jsse.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.net.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.net.openssl.ciphers.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.net.openssl.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.scan.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.security.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>org.apache.tomcat.util.threads.res.LocalStrings</includeResourceBundle>
+      <includeResourceBundle>javax.servlet.LocalStrings</includeResourceBundle>
+      
<includeResourceBundle>javax.servlet.http.LocalStrings</includeResourceBundle>
+    </includeResourceBundles>
+    <extensionProperties>
+      <extension.annotation.custom.annotations.properties>
+        
javax.json.bind.annotation.JsonbProperty:allDeclaredConstructors=true|allDeclaredMethods=true|allDeclaredFields=true,
+        org.apache.meecrowave.runner.cli.CliOption:allDeclaredFields=true
+      </extension.annotation.custom.annotations.properties>
+      <extension.openwebbeans.extension.excludes>
+        org.apache.cxf.Bus,org.apache.cxf.common.util.ClassUnwrapper,
+        org.apache.cxf.interceptor.InterceptorProvider,
+        io.yupiik.logging.jul,
+        org.apache.openwebbeans.se
+      </extension.openwebbeans.extension.excludes>
+    </extensionProperties>
+    <customOptions> <!-- force JUL usage since Log4j2 does not work well at 
all on GraalVM -->
+      
<customOption>-Dopenwebbeans.logging.factory=org.apache.webbeans.logger.JULLoggerFactory</customOption>
+      
<customOption>-Djava.util.logging.manager=io.yupiik.logging.jul.YupiikLogManager</customOption>
+    </customOptions>
+  </configuration>
+</plugin>
+----
+
+In terms of dependencies you can start with this for example:
+
+[source,xml]
+----
+<dependencies>
+  <dependency>
+    <groupId>org.apache.meecrowave</groupId>
+    <artifactId>meecrowave-specs-api</artifactId>
+    <version>${meecrowave.version}</version>
+  </dependency>
+  <dependency>
+    <groupId>org.apache.meecrowave</groupId>
+    <artifactId>meecrowave-core</artifactId>
+    <version>${meecrowave.version}</version>
+  </dependency>
+  <dependency> <!-- we use this to have a reconfigurable JUL runtime in native 
binary -->
+    <groupId>io.yupiik.logging</groupId>
+    <artifactId>yupiik-logging-jul</artifactId>
+    <version>1.0.0</version>
+  </dependency>
+  <dependency> <!-- using openwebbeans arthur knight, graalvm will use the 
scanner service from this module -->
+    <groupId>org.apache.openwebbeans</groupId>
+    <artifactId>openwebbeans-se</artifactId>
+    <version>2.0.22</version>
+  </dependency>
+  <dependency>
+    <groupId>commons-cli</groupId>
+    <artifactId>commons-cli</artifactId>
+    <version>1.4</version>
+  </dependency>
+</dependencies>
+----
+
+TIP: using a profile or a binary dedicated module you can keep the JVM mode 
using Log4j2 and the native mode using Yupiik Logging (just tweak dependencies 
and optionally use arthur exclude configuration).
+
+TIP: an Arthur knight can be developed to replace all that configuration, it 
will auto-setup meecrowave/cxf/tomcat needed reflection, scan present tomcat 
and cxf bundles, auto register CXF SPI (bus-extensions.txt - optionally 
filtering them and the not loadable ones) classes for reflection, spec classes 
(`org.apache.cxf.jaxrs.utils.InjectionUtils.STANDARD_CONTEXT_CLASSES`), and 
likely inherit from openwebbeans extension CDI integration.
+It means that once done, using meecrowave can be as simple as 
`<graalExtension>meecrowave</graalExtension>`. If you think it is worth the 
effort, don't hesitate to do a pull request on Arthur or send a mail on 
d...@openwebbeans.apache.org.
+
+With this setup you should get a `target/*.graal.bin` binary executable 
containing your application and meecrowave, just launch it to start your 
application and use it as a standard Meecrowave CLI!
+
+IMPORTANT: until Apache OpenWebBeans 2.0.22, annotated mode can miss some 
beans, ensure to use 2.0.22 or more if you don't explicitly add a beans.xml.
+
+NOTE: you can need to adjust a few classes depending what you use of CXF. 
Previous setup will be sufficient for a module containing:
++
+[source,java]
+----
+// test with:
+// $ curl http://localhost:8080/hello?name=foo -H 'accept: application/json'
+@Path("hello")
+@ApplicationScoped
+public class MyEndpoint {
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Message get(@QueryParam("name") final String name) {
+        return new Message("Hello " + name + "!");
+    }
+
+    @Data
+    public static class Message {
+        @JsonbProperty // mark at least one property to let arthur find it, 
see extension.annotation.custom.annotations.properties
+        private String message;
+    }
+}
+----

Reply via email to