How to deploy a Vaadin application as a war file?

Hi,

I have created my first Vaadin application with eclipse using the Vaadin 7 wizard. It runs fine within eclipse.
But how do you deploy the app on a remote tomcat server?

In other projects I have an ant script that builds the war file. But the Vaadin projects have a different structure. I believe they are “dynamic web projects” in eclipse. How do you create a war file?

Thanks
Magnus

Post
Hudson + Ivy/Ant + Vaadin
contains full ant build script.

Thanks!

When building with ant it is missing the deployment descriptor web.xml. I did not check the check box “create deployment descriptor” in the vaadin project wizard.

Is the deployment descriptor needed? If yes, can I simply add a web.xml file to my project? What would be the contents?
If no, how can I get around with the ant error message?

Thanks
Magnus

Add just
needxmlfile=“false”
parameter to the the
war
task.

Ok, one step further! :slight_smile:

But now Vaadin classes are missing at runtime:

java.lang.NoClassDefFoundError: com/vaadin/server/VaadinServlet

I found on the net that vaadin-server.jar should be available somewhere. But there is no such file in my project tree.
What’s this?

Magnus

You probably use
ivy
for dependency management. Check your
ivy.xml
and
ivysettings.xml
file. Before making a
war
file, you need to retrive all needed jars (also contained in
buld.xml
).

Hi,

I don’t know anything about ivy, but I have noticed that the Vaadin wizard created the ivy files (see below).

How do I have to change them in order to get my app deployed?

Thanks
Magnus

ivy.xml:

[size=1]
[font=courier new]
<?xml version="1.0"?>
<!DOCTYPE ivy-module [
    <!ENTITY vaadin.version "7.1.15">
]>
<ivy-module version="2.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
    <info organisation="com.example" module="v7proj" />
    <configurations>
        <!-- The default configuration, which should be deployed to the server -->
        <conf name="default" />
        <!-- A configuration only needed when compiling the widget set. Should 
            not be deployed to the server -->
        <conf name="widgetset-compile" />
        <!-- A configuration used in compilation of server side classes only.
            Should be deployed to the server -->
        <conf name="nodeploy" />
    </configurations>
    <dependencies defaultconf="default" defaultconfmapping="default->default">
        <!-- The core server part of Vaadin -->
        <dependency org="com.vaadin" name="vaadin-server" rev="&vaadin.version;" />

        <!-- Vaadin themes -->
        <dependency org="com.vaadin" name="vaadin-themes" rev="&vaadin.version;" />

        <!-- Push support -->
        <dependency org="com.vaadin" name="vaadin-push" rev="&vaadin.version;" />

        <!-- Servlet 3.0 API -->
        <dependency org="javax.servlet" name="javax.servlet-api" rev="3.0.1" conf="nodeploy->default" />

        <!-- Precompiled DefaultWidgetSet -->
        <dependency org="com.vaadin" name="vaadin-client-compiled"
            rev="&vaadin.version;" />

        <!-- Vaadin client side, needed for widget set compilation -->
        <dependency org="com.vaadin" name="vaadin-client" rev="&vaadin.version;"
             conf="widgetset-compile->default" />

        <!-- Compiler for custom widget sets. Should not be deployed -->
        <dependency org="com.vaadin" name="vaadin-client-compiler"
            rev="&vaadin.version;" conf="widgetset-compile->default" />
    </dependencies>
</ivy-module>
[/font]
[/size]

ivysettings.xml:

[size=1]
[font=courier new]
<?xml version="1.0" encoding="UTF-8"?>
<ivysettings>
    <settings defaultResolver="default" />
    <resolvers>
        <chain name="default">
            <!-- Public Maven repository -->
            <ibiblio name="public" m2compatible="true" />

            <!-- Vaadin Add-on repository -->
            <ibiblio name="vaadin-addons" usepoms="true" m2compatible="true"
                root="http://maven.vaadin.com/vaadin-addons" />

            <!-- Vaadin snapshots repository -->
            <ibiblio name="vaadin-snapshots" usepoms="true" m2compatible="true"
                root="https://oss.sonatype.org/content/repositories/vaadin-snapshots" />
            <!-- Repository used for Vaadin modified smartsprites library -->
            <dual name="custom-smartsprites">
                <filesystem name="smartsprites-ivy">
                    <ivy pattern="${basedir}/ivymodule/[module]
-ivy-[revision]
.xml" />
                </filesystem>
                <url name="smartsprites-artifact">
                    <artifact
                        pattern="http://dev.vaadin.com/svn/versions/6.8/build/smartsprites/lib/[artifact]
(-[revision]
).[ext]
" />
                </url>
            </dual>
        </chain>
    </resolvers>
    <modules>
        <!-- Vaadin patched SmartSprites -->
        <module organisation="com.carrotsearch" name="smartsprites"
            revision="0.2.3-itmill" resolver="custom-smartsprites" />
    </modules>


</ivysettings>
[/font]
[/size]

If you are using Eclipse and just want the war, then you can always in Eclipse just press File → Export → Web → WAR File. That is if you actually don’t want the ant script for some CI server running automated builds.

You mentioned that you don’t have a web.xml file. Java web projects uses the servlet api. Servlet 2.x needs a web.xml file. Servlet 3.0 introduced having annotations in Java to do the same. You probably have the relevant annotations in your UI class. You can still have a web.xml with Servlet 3.0, but you don’t have to.

I don’t have a ready answer on how to get the ivy dependencies noticed in the ant script. It is not a change in the ivy scripts, but a change in the ant script, I would guess. It has at least a row which is the location they would be in if you wouldn’t use a dependency management system.

Personally I have been using Maven exclusively as of late. It has the same dependency management as Ivy (Ivy uses Maven’s dependencies) and it has it’s own build tool so it knows how to build things. I really like it since I learned it properly (before that I hated it :)).

Hi,

well, I actually cannot tell if ivy is the problem or the ant script. I only see the runtime error after deploying a simple application as a war file to my remote tomcat server:

java.lang.NoClassDefFoundError: com/vaadin/server/VaadinServlet So the first idea is a missing jar file. And indeed, there is no vaadin*.jar file in my project tree. The project was created by the Vaadin project wizard for eclipse, and I don’t believe that this is a bug in the project wizard. But there must be some jar file missing, because of the NoClassDefFoundError.

Now this thread brings ivy into the focus. I don’t know ivy, and I cannot imagine how ivy could solve the NoClassDefFoundError. I just want a simple test case to compare Vaadin against GWT development. But I cannot get my simple application running on my tomcat server.

Here is what I have done:

  1. Create a new Vaadin 7 project with the Vaadin project wizard in eclipse (without a web.xml).
  2. Test it within eclipse and it runs fine.
  3. Add an ant script “prj.xml” to build the war file (see below).
  4. Build the war file with the ant script.
  5. Deploy the war file to my remote tomcat server.
  6. See the NoClassDefFoundError mentioned above.

I believe that there is nothing special in this procedure. Thousands of developers must have done this and there must be a standard way to do it. I would appreciate any help.

Thank you,
Magnus

prj.xml:

[size=1]
[font=comic sans ms]
<project name="sms" basedir="." default="default">

 <property name="class.dir" value="build/classes"/>
 <property name="lib.dir" value="WebContent/WEB-INF/lib"/>

 <target name="default" depends="clear,buildwar,deploy"></target>

 <target name="buildwar">
  <war basedir="WebContent" destfile="sms.war" needxmlfile="false" manifest="WebContent/META-INF/MANIFEST.MF"> <!-- webxml="WebContent/WEB-INF/web.xml"> --> 
   <classes dir="${class.dir}" />
  </war>
 </target>

 <target name="deploy">
 <!-- <copy file="bcs.war" todir="." /> -->
 </target>

 <target name="clear">
  <delete file="sms.war"/>
 </target>
 
</project>
[/font]
[/size]

Hi Magnus,
if you want to create the war just once, it is really the easiest way to export the project as Jens wrote above.
When you want to use ant script, you really need task, which retrives requested jars, that
are
contained in your project tree (see attached screenshot and look at your project’s classpath).When you look at original build scripts it contains tasks as
retrieve
and
retrieve-for-widgetset.
To get a full war you need at least call tasks:
resolve → retrive →

makewar
.[i]

[/i]If you have custom theme you need also
compile-styles
, if you use not default widgetset -
build-widgetse
t.

Forgot the attachment :slight_smile:
15339.png

Yup, test out Eclipse’s export to war.

For ant, you need an updated ant script that knows about ivy. I found one example here https://github.com/canthony/simple-vaadin-7-compile-widgetset-ivy/blob/master/build.xml. It does war-building, widgetset compilation as well as theme compilation. Notice in the beginning all the ivy:... tags. There it fetches the needed dependencies (that you are missing) from Ivy. You might have to install an additional plugin for ant so that it understands how to use Ivy. Within eclipse you can install something called Apache Ivy Ant Tasks. You might have it already as your eclipse understands on Ivy in general.

Hi,

thank you. When exporting the war file manually, it contains a lot of more stuff, especially the vaadin-server*.jar file and a lot of more.

However, I would like to automate this with ant. Since I just created the app with the vaadin project wizard, there is nothing special about it. So there must be some standard ant script to do it.

My problem is that I do not understand the deployment process, but it must be different from what I know:

  • In my pure GWT-projects, I can use my ant script above. It collects all the classes and jar in the project tree. And this is enough, because the project tree contains everything that is needed.
  • With Vaadin, not everything is contained in the project tree. For example, I did not see any vaadin*.jar files in my project tree.

So there must be something additional. I guess that the ant script must collect the jar files from other locations somehow. Is this the job of ivy?

The build.xml you provided contains a lot of stuff. But when looking at the tag I cannot see additional locations that are incorporated. Therefore I guess that the tags will copy the needed files into the project tree, right? Which one of the 4 ivy tags will do this?

Magnus

PS: I still wonder why there isn’t a standard solution od best practice, because every Vaadin beginner must need it…

Right. Sorry for the confusion and not having a standard way to go right of the bat. I’ll run you trough the techs here.

You can have Vaadin apps without Ivy at all - it was just introduced as the standard way the Eclipse plugin sets up the app structure at one point. Here is the problem that you want to solve and this goes beond Vaadin. Let’s say you work with one technology a lot, be it Vaadin, GWT or Hibernate. Over the time you’ve gathered a lot of projects. Some real, some small prototyping. I bet I’ve set up somewhere around 50-200 Vaadin projects just to do a quick test of something. With the conventional ways of having all jars in the project structure, that means that you have say 100 copies of Vaadin around on your hard drive. One full copy of it is around 50mb so that is 5 gigabytes of data right there.

What dependency managers try to fix is this exact problem. Instead of having all those copies of log4j-2.4.0.jar, it will only download it once into one place, and then say to all projects that use that file over there. Now your 5gb of Vaadin is again 50mb for all your projects. When you check in the project into source control, it is enough to put the project descriptor (ivy.xml) in there instead of all dependencies. A few hundred megabytes of data replaced with a couple kilobytes of text. You can check on your harddrive this central place where all the jars live. It should be a .ivy2 folder in your home directory on any operating system. On my Windows computer, it is C:\Users\Jens.ivy2. Within it there is for example C:\Users\Jens.ivy2\cache\com.vaadin\vaadin-server\jars\vaadin-server-7.2.3.jar.

So enough of a sales pitch for dependency managers. The problem you are facing is indeed the one that you mentioned. Everything isn’t in the project structure. What is missing are the dependency jars. That’s why you have to fetch them from your central repository in your ant script while building the war. In fact, you could download the
all-in-one Vaadin package
, put the jars into the projects WebContent/WEB-INF/lib, remove Ivy from the project alltogether and then your standard build script would work.

So back to the build script. I’m not completely sure what does what. I guess the ivy:resolve is the one that goes trough your ivy.xml to see which dependencies the project uses, fetches them from your central Ivy repository and adds them to the classpath so that the compile step is successful. Then to also include the jars into the war you would need the <ivy:cachefileset setid=“ivy.deps.default.fileset” conf=“default”/> one. This is my guess based on the target=“war” code in the end: <copy todir="${workdir}/WEB-INF/lib" flatten="true"> <fileset refid="ivy.deps.default.fileset"/> </copy> so it seems to copy all needed dependencies from Ivy repository to the project structure. I would have all four rows in there, just in case. In fact, the github project I linked to is a Ivy + Ant example project with nothing else, so you should be able to copy build.xml and build.properties into your project, configure build.properties according to your project and run command line ‘ant’ to get a war out of it.

Long post. I probably missed a bunch of things. Ask away if you come up with any.