App construction with Apache Meecrowave

Apache Meecrowave is a MicroProfile server and Apache project that can be described as the “Spring Boot of the EE world”, except one that only uses Apache software. Sven Ruppert goes over what developers need to know about this customizable server and how it works so well with Vaadin.
Preparation: The Apache Meecrowave project can be found on OpenWebBeans. The source codes can be found at GitHub.
The Apache Meecrowave basics
The Apache Meecrowave project itself is quite manageable. Essentially, it’s a shell that contains existing Apache technologies and unites them. The root of the matter is Apache Tomcat, which functions as a servlet container and provides the runtime environment. Other components include:
- CDI – OpenWebBeans
- JAX-RS – CXF
- JSON – Johnzon
All together, the JAR weighs in at 9 MB, a fairly small size these days. That leaves space for the addition of your own application and the following dependencies. In order to work with the Meecrowave package, we will also add the following dependencies to our Maven project. (Gradle is also an option.) This gives us a foundation we can build upon.
<dependency> <groupId>org.apache.meecrowave</groupId> <artifactId>meecrowave-core</artifactId> <version>${meecrowave.version}</version> </dependency>
To start an instance, Meercrowave creates a class called main
(other names can be chosen) and thus a classic main
method is defined.
public static void main(String[] args) { new Meecrowave(new Meecrowave.Builder() { { randomHttpPort(); setTomcatScanning(true); setTomcatAutoSetup(false); setHttp2(true); setTempDir("target/meecrowave/" + System.nanoTime()); setUseShutdownHook(true); } }) .bake() .await(); }
The Meecrowave project offers the user a builder to program and configure an instance. This instance is then the commit argument in the constructor.
A subsequent start (bake
) and waiting or holding of the instance (await
) complete the startup process. By the way, the configuration options that we just used in the code example are just for demonstration purposes.
Now that we have a running instance, we can try the first Hello World
.
SEE ALSO: Apache NetBeans: From open source to open governance
Hello World with REST
Let’s turn our attention towards the obligatory Hello Word. In our case, we start with Hello World
in order to make a REST endpoint available. To do this, a class with the name HelloEndpoint
and the following content is generated within the class path:
@Path("hello") @ApplicationScoped public class HelloEndpoint { @GET @Produces(MediaType.APPLICATION_JSON) public String sayHi() { return "Hello World"; } }
At the start of the container, the class is found, the endpoint is registered, and the utilization can begin. In order to verify this, you can also write the first test. The Meecrowave project also comes along with an extension for JUnit4 and JUnit5.
If you want to utilize these extensions, you must enter the following dependency in the pom.xml
file. Also, do not forget the JUnit5 dependencies.
<!--TDD Extension for Meecrowave--> <dependency> <groupId>org.apache.meecrowave</groupId> <artifactId>meecrowave-junit</artifactId> <scope>test</scope> <version>${meecrowave.version}</version> </dependency>
In order to test this endpoint, we are going to boot up the container at the start of the test. Since the port is assigned dynamically, you can read out this as well as other information from the Builder configuration. The JUnit5 extension MonoMeecrowaveConfig injects the currently valid configuration instance.
@MonoMeecrowaveConfig public class HelloEndpointTest { @ConfigurationInject private Meecrowave.Builder configuration; @Test public void hello() { final Client client = ClientBuilder.newClient(); try { assertEquals("Hello World", client.target("http://localhost:" + configuration.getHttpPort()) .path("/hello") .request(APPLICATION_JSON_TYPE) .get(String.class)); } finally { client.close(); } } }
SEE ALSO: Apache Groovy 2.5 arrived: Major improvements and a bright future
Hello World with HttpServlet
Let’s move over to our first example, which is based on HttpServlets. Again, we are going to test a simple Hello World. But in this case, we are going one step further by providing a minimal function through the CDI of the servlet instance.
@WebServlet("/*") public class HelloWorldServlet extends HttpServlet { @Inject private UpperCaseService service; public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/plain; charset=utf-8"); String value = request.getParameter("value"); response.getWriter().println(service.upperCase(value)); } }
@Dependent public class UpperCaseService{ public String upperCase(String txt) { return txt.toUpperCase(); } }
Even here, it’s enough to provide the classes in the current class path. So, an @Inject
works just fine. If you use JUnit4 in your project, you can take a look at the example shown below on how to write the test. The procedure itself is the same as before, but this time the information is provided by using @Rule
.
public class HelloWorldServletTest { @Rule public final MeecrowaveRule rule = new MeecrowaveRule(); @Test public void test001() { final Client client = ClientBuilder.newClient(); try { assertEquals("HALLONASE", client.target("http://127.0.0.1:" + rule.getConfiguration().getHttpPort()) .queryParam("value", "HalloNase") .request(APPLICATION_JSON_TYPE) .get(String.class) .trim()); } catch (Exception e) { Assert.fail(e.getMessage()); } finally { client.close(); } } }
SEE ALSO: Apache Flink 1.5.0 is here: Smooth streaming and batch data processing
The first application with Vaadin V8
So, now that we had our first experience with Meecrowave and the use of Servlets, we can begin with our first Vaadin 8-based RIA application. Why should developers choose Vaadin 8, when Vaadin 10 has just come out? Well, there are several reasons. The very first one is the fact that it is still necessary to specify the servlet with Vaadin 8. The following code snippet is a continuation of the previous example and it shows how easy and fast it is to start developing a single-page web application.
Vaadin 8 is used by almost half of all Fortune 100 companies and it will continue to be developed until at least February 2022. So, a look at Vaadin 8 is still worthwhile today. To use Vaadin 8, the following dependencies must be defined in pom.xml
.
<dependencyManagement> <dependencies> <!--Vaadin --> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-bom</artifactId> <version>${vaadin.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--Vaadin --> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-server</artifactId> </dependency> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-themes</artifactId> </dependency> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-client-compiled</artifactId> </dependency> </dependencies>
Let’s begin with the servlet, the linchpin of the web application. Here, we define the UI class (in this case, MyUI
) which should be used simply by annotation.
@WebServlet("/*") @VaadinServletConfiguration(productionMode = false, ui = MyUI.class) public static class MyProjectServlet extends VaadinServlet { }
The MyUI
class is very simple. It only contains a button that creates a new label and adds it to the view.
public class MyUI extends UI { @Override protected void init(VaadinRequest request) { final Layout layout = new VerticalLayout(); layout .addComponent(new Button("click me", event -> layout.addComponents(new Label("clicked again")) )); //set the main Component setContent(layout); } }
SEE ALSO: Hunt cyber threats with community-driven Apache Spot
The first application with Vaadin 10
Finally, we are going to take another look at a Hello World, this time with Vaadin 10. The difference between the two versions is that it is no longer necessary to specify the servlet with Vaadin 10. Therefore, it is sufficient enough to specify the route that belongs to the UI component by annotation. In our case, the component can directly be accessed under /
. In this case, the corresponding servlet provides the framework and the basic procedure is very similar.
@Route("") public class HelloVaadinV10 extends Composite<Div> { public HelloVaadinV10() { final VerticalLayout layout = new VerticalLayout(); layout .add(new Button("click me", event -> layout.add(new Label("clicked again")) )); //set the main Component getContent().add(layout); } }
There are still some other differences between the Vaadin 8 and 10 platform, but I won’t go into more detail at this point. I would just like to highlight the most important point: Vaadin 8 was based on GWT. For the Vaadin 10 platform, everything is based on WebComponents.
I also want to refer at this point to the corresponding documentation. I am going to write more about this subject here on JAXenter.com in the future.
SEE ALSO: Apache Wicket 8: Write less, achieve more with this Java framework
Conclusion
All in all, the “Meecrowave & Vaadin” team is very effective and worth a look. Once the dependencies are defined, you can start creating the UI immediately. The turnaround times are very low and restarting Meecrowave and Vaadin together takes less than 500ms on my laptop. Developers can create a UI prototype themselves with a simple IDE, Meecrowave and Vaadin, after setting up a few basic requirements.
If you want to see the source code for this article, don’t miss the demos on GitHub.
I think this article is very helpful for the app developer. But I am not an app developer. I want to create an application for my Apple Customer Support. If possible then help me.
Hi Joe,
not 100% sure what you mean. But you can ping me directly. sven at vaadin.com Cheers Sven