This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

Create WildFly Swarm applications from existing war files

Have you heard about WildFly Swarm?

It's a new sidecar project to WildFly which helps you create self-contained Java microservices based upon the normal WildFly application-server.

Sounds interesting?

We had different use-cases for such a product. Our VisionX creates war files and desktop applications. It would be nice to have a microservice option. Our idea was to create a WildFly Swarm application based on our pre-created war files. Could be useful.

We made some experience with bundeling an embedded Tomcat with our applications because we use this variant for our desktop applications to add browser based help systems. We thought that a replacement of embedded Tomcat could reduce complexity...

The documentation was simple and maven based. The info:

We do aim to add support for other build-systems in the near future.

was nice but the relevant information wasn't available for ANT. We found some gradle tasks, but nothing for ANT - because ANT isn't supported.
What's the problem with maven? We don't like downloading the Internet for simple dependency management. This happened during our first tests with WildFly Swarm. Before we built our first "fat" jar, the "whole JBoss repository" was downloaded.

Test: Phase 1

We tried to follow the documentation and started with a new Maven "war" project. Our application was a simple JVx application with vaadin UI. The application code:

@Push
@Widgetset(value = "com.sibvisions.rad.ui.vaadin.ext.ui.Widgetset")
@Configuration({@Parameter(name = "main", value = "com.sibvisions.demos.swarm.EmbeddedApplication$MyApplication")})
@SuppressWarnings("serial")
public class EmbeddedApplication extends VaadinUI
{
    @WebServlet(value = {"/minimal/*", "/VAADIN/*"}, asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = EmbeddedApplication.class)
    public static class Servlet extends VaadinServlet
    {
    }   // Servlet

    public static class MyApplication extends Application
    {
        public MyApplication(UILauncher pLauncher)
        {
            super(pLauncher);
           
            setName("Simple application");

            setLayout(new UIBorderLayout());
           
            UILabel lblHello = new UILabel("Hello JVx' vaadinUI");
            lblHello.setFont(UIFont.getDefaultFont().deriveFont(UIFont.BOLD, 16));
            lblHello.setHorizontalAlignment(IAlignmentConstants.ALIGN_CENTER);
            //example CSS without custom css file
            ((VaadinLabel)lblHello.getUIResource()).getCssExtension().addAttribute("margin-top", "100px");
           
            add(lblHello, UIBorderLayout.CENTER);
        }        
    }    
}

We found an intro from vaadin about their tests with WildFly Swarm. The last link contains redirects to a github project with many examples and a ready-to-use maven configuration.

But, we had bad luck because no example was working with our setup. The build wasn't a problem, but we got some Exceptions at runtime. We tried to find documentation in the Internet, but we didn't find a solution because the project is in Alpha status and documentation is not yet ready... So we tried to build WildFly Swarm on our own to be able to add debug messages.

After a long maven fight (once again) everything was working. We had some problems with JDK 8 and Eclipse Kepler because Kepler didn't support JDK8 without a Patch and bundled maven was too old. Latest maven didn't work with Eclipse but 3.2.1 was working...
WildFly Swarm test artifacts didn't work without problems and we had to fix some autoboxing errors (because of our custom compiler settings). Horrible but we won the fight!

The problem with our "fat" jar was that two dependencies were missing or weren't resolved correctly. After we manually set two more dependencies:

<dependency>
  <groupId>org.jboss.msc</groupId>
  <artifactId>jboss-msc</artifactId>
  <version>1.2.6.Final</version>
</dependency>
<dependency>
  <groupId>org.jboss.spec.javax.sql</groupId>
  <artifactId>jboss-javax-sql-api_7.0_spec</artifactId>
  <version>1.1.0.Final</version>
</dependency>

our "fat" jar was working without problems.

BUT... the jar had about 100 MB! Our war file had about 40MB. The overhead was about 60MB - WTF?
Our applications with embedded Tomcat had an overhead of 4MB.

The problem was/is that all maven dependencies were added to the war and the jar file. It was handled by the swarm-plugin and the issue #107 explains the problem.

After one day! we had a working Hello world example as Maven project. Sure, we built our own WildFly Swarm version too.

Test: Phase 2

The Maven project was working and maven built a war for our sources and bundled all dependencies for us, but what about existing war files? Our initial plan was the creation of WildFly Swarm applications for existing war files. This wasn't possible without hacking because it wasn't implemented... for us.

I told you that we built our own WildFly Swarm version and also the swarm-plugin. The plugin had a PackageMojo class. This mojo had enough documentation (= source code) for us, to create a simple test case for our use-case.

The test class is about 100 LoC with minimal logic but it's tricky. The relevant calls:

BuildTool tool = new BuildTool();

for (File jar : findMinimalDependencies())
{
  //read groupid, artifactid, version from jar

  tool.dependency("compile", sGroupId, sArtifactId, sVersion, "jar", null, jar);
}

tool.artifactResolvingHelper(new Resolver(tool));
tool.projectArtifact("com.sibvisions.demos", "swarm", "0.2-SNAPSHOT", "war", war);
tool.build("swarm-0.2-SNAPSHOT", target);

The Resolver was a simply code copy of BuildTool findArtifact method:

public class Resolver implements ArtifactResolvingHelper
{
    private BuildTool tool;
   
    public Resolver(BuildTool pTool)
    {
        tool = pTool;
    }

    @Override
    public ArtifactSpec resolve(ArtifactSpec pSpec) throws Exception
    {
        for (ArtifactSpec each : tool.dependencies())
        {
            if (each.file == null) {
                continue;
            }
           
            if (pSpec.artifactId != null && !pSpec.artifactId.equals(each.artifactId)) {
                continue;
            }

            if (pSpec.version != null && !pSpec.version.equals(each.version)) {
                continue;
            }

            if (pSpec.packaging != null && !pSpec.packaging.equals(each.packaging)) {
                continue;
            }

            if (pSpec.classifier != null && !pSpec.classifier.equals(each.classifier)) {
                continue;
            }

            return each;
        }

        return null;
    }  
}

(Sure, not the best solution - but it was good enough for our tests)

With our test class, it was possible to create a WildFly Swarm application for an existing war file, without problems and without maven. And the best: The "fat" jar file had about 83MB and the original war file was about 60MB. The overhead was 23MB, but awesome for a basic WildFly installation.

The example project of Phase 1 is available on github.

Conclusion

WildFly Swarm is a nice product but it's not ready-to-use. If you have time to play around with it, just do it because it creates a back to the roots feeling - back to hacking. The "fat" jars are a nice idea, but microservice is just a buzzword.

WildFly is not comparable to embedded Tomcat, but if you need a simple application server for your servlets, an embedded Tomcat or Jetty are good enough. We won't replace our embedded Tomcat with WildFly Swarm because we misunderstood the concept and both products are for different use-cases.... but a new export Option for VisionX should be possible!

3 Responses to “Create WildFly Swarm applications from existing war files”

  1. Ken Finnigan says:

    Thanks for taking a look at WildFly Swarm! We're always looking to hear ways it can be improved.

    The size of the "fat" jars being generated for WildFly is certainly an area we need to work on, as it is also a concern of ours.

    It would be fantastic if you were able to contribute the Ant Task you created for this. As we already support Maven and Gradle it would be great to add Ant as well.

    Thanks for the idea of wrapping a WAR with WildFly Swarm. I've linked to your blog from an issue we have covering that topic: https://github.com/wildfly-swarm/wildfly-swarm/issues/5. Any contributions of how you did it, or other ideas on how it could work, would be greatly appreciated.

    Thanks again for trying out the not-ready-for-production Alpha release and please check back often for updates.

  2. rjahn says:

    Thanks for your comment!

    I didn't create an ANT task, it's a simple JUnit test case. The only problem is that all relevant swarm libs and dependencies were collected with a dirty hack in your swarm-plugin. It shouldn't be a problem to get all dependencies automatically becasue maven has this feature. I always start with minimum dependencies because if everything is working as unit test, it's easy to create tool support.

    My solution is currently fixed to Alpha4 and I didn't know what's on your roadmap for the final release. So, I didn't create a future-proof solution and it was more a PoC. If you're going to change your BuildTool, everything can be different.
    But I'll move my project to github after I found a solution for my dirty code.

    But, both thumbs up for your work!

  3. rjahn says:

    The source code is online: https://github.com/rjahn/swarm-ant

    There's an ant task to create the jar from an existing war file. Add all additional dependencies to ivy.xml and it should work like a charm.

    Ivy was needed for a resolver because BuildTool scans module dependencies....
    The task has an option to save all dependencies (saved in directory: build/swarmlibs, build/swarmlibs/resolved)

    If you have all dependencies, it's also possible to work without ivy (an offline variant)

    The solution works for my use-case and isn't production ready :)

Leave a Reply

Spam protection by WP Captcha-Free