Vaadin std prod project includes vaadin-client-compiler and jetty? - maven

I get vaadin-client-compiler artifact (which brings Jetty with it) included with my production project. Am I supposed to ?
To reproduce I'm starting from scratch and letting Maven generate a Vaadin multimodule project for me:
mvn
-DarchetypeGroupId=com.vaadin
-DarchetypeArtifactId=vaadin-archetype-application-multimodule
-DarchetypeVersion=7.6.2
-DarchetypeRepository=http://repo.maven.apache.org/maven2/
-DgroupId=com.acme
-DartifactId=VaadinTest1
-Dversion=1.0.0-SNAPSHOT
-Dpackage=com.acme.vaadintest1
-Dbasedir=D:\\dev\\java
-DthemeName=mytheme
-DwidgetsetName=MyAppWidgetset
-DuiName=MyUI
-Darchetype.interactive=false
--batch-mode archetype:generate
Then in the parent project I execute:
mvn -Pproduction clean install
After this is done I look into the WAR file generated in the "xxx-production" project and notice it contains vaadin-client-compiler, Jetty, and what not.
I've found this ticket and by looking at the last comment it seems I shouldn't have anything like that in my production WAR. I hesitate to change my POMs as they are generated by the archetype and I guess at some level supposed to represent kind of a Vaadin best-practice approach. I wouldn't want to second guess that. Or ?
The problem with these artifacts being part of the classpath is that
it balloons the size of the WAR
it creates some problems wrt Atmosphere which supposedly gets confused because it finds Jetty on the classpath. (Atmosphere is used under the hood by Vaadin)
The result is that you'll get SEVERE error like this in the log when deploying on Tomcat 8:
14-Feb-2016 16:42:30.368 SEVERE [localhost-startStop-1] org.atmosphere.cpr.DefaultAsyncSupportResolver.newCometSupport Failed to create comet support class: class org.
atmosphere.container.JettyServlet30AsyncSupportWithWebSocket, error: null
To sum up:
Is it correct that I'm not supposed to have these artifacts in a
Vaadin 7.6.2 production project ?
How to solve ?

I believe I've found the answer. It seems Vaadin team was/is fully aware of this but it is kind of a left-over from the old days when there was some kind of annoying bug.
In your xxx-widgetset project you'll see something like this in the POM for that project:
<dependencies>
<!-- Versions for these are configured in the parent POM -->
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client</artifactId>
<!-- TODO this should have scope provided once http://dev.vaadin.com/ticket/14788 is resolved -->
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiler</artifactId>
<!-- TODO this should have scope provided once http://dev.vaadin.com/ticket/14788 is resolved -->
<!-- <scope>provided</scope> -->
</dependency>
... you'll see more deps here if you've added
... Vaadin add-ons to your project.
</dependencies>
See the TODO comments ??
Well, it just so happens that the bug mentioned in ticket 14788 doesn't happen anymore, at least not on 7.6.2. So you can now safely do what the TODO comment says.
This has reduced my WAR size by 50-70 pct.
It seems to me there's no longer any good reason why this archetype generation doesn't actually do what TODO comment says. Currently you'll have to manually correct it every time you generate a new project skeleton.

If you work with a different webserver (in your case Tomcat 8) you don't need the provided jetty-plugin.
As the archetype has some jetty-dependencies you can exclude them with the
exclusions tag in the Maven POM file.
Example
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiler</artifactId>
<version>${vaadin.version}</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</exclusion>
</exclusions>
Moreover delete/comment out all unnecessary "jetty" dependencies found in the module POM files.

Related

Flex Maven project compilation error: Global artifact is not available. Make sure to add 'playerglobal' or 'airglobal' to this project

I am converting an existing flex project to a maven project using the IntelliJ IDEA. As per the R&D on google, I have added the pom.xml file and I have resolved multiple issues by adding the required dependencies. However, I am stuck at one point now where despite adding the required dependency in pom file, the 'compile' goal keeps throwing error.
Error:
Failed to execute goal
net.flexmojos.oss:flexmojos-maven-plugin:7.1.0:compile-swf
(default-compile-swf) on project TA_UI_Test1:
java.lang.reflect.InvocationTargetException: Global artifact is not
available. Make sure to add 'playerglobal' or 'airglobal' to this
project. -> [Help 1]
pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>TA_UI_Test1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>swf</packaging>
<name>TA_UI_Test1 Flex</name>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>net.flexmojos.oss</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>7.1.0</version>
<extensions>true</extensions>
<configuration>
<sourceFile>Main.mxml</sourceFile>
<debug>true</debug>
<!--<swfVersion>11</swfVersion>-->
<!--<targetPlayer>10.2</targetPlayer>-->
</configuration>
<dependencies>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>4.6.b.23201</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>flex-compiler-oem</artifactId>
<version>4.1.0.16076</version>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>mxmlc</artifactId>
<version>4.1.0.16076</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.adobe.flex.framework</groupId>-->
<!--<artifactId>playerglobal</artifactId>-->
<!--<version>10-3.3.0.4852</version>-->
<!--<type>swc</type>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>com.adobe.flex.framework</groupId>-->
<!--<artifactId>playerglobal</artifactId>-->
<!--<version>4.5.1.21328</version>-->
<!--<classifier>10</classifier>-->
<!--<type>2.swc</type>-->
<!--</dependency>-->
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>playerglobal</artifactId>
<version>3.2.0.3958</version>
<classifier>9</classifier>
<type>swc</type>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>flex-framework</artifactId>
<version>4.6.b.23201</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>asdoc</artifactId>
<version>4.6.b.23201</version>
</dependency>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>4.6.b.23201</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>flex-compiler-oem</artifactId>
<version>3.6.0.16995</version>
</dependency>
<dependency>
<groupId>com.adobe.flexunit</groupId>
<artifactId>flexunit</artifactId>
<version>0.85</version>
<type>swc</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>mxmlc</artifactId>
<version>4.1.0.16076</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.adobe.flex.framework</groupId>-->
<!--<artifactId>playerglobal</artifactId>-->
<!--<version>10-3.3.0.4852</version>-->
<!--<classifier>10.2</classifier>-->
<!--<type>swc</type>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>com.adobe.flex.framework</groupId>-->
<!--<artifactId>playerglobal</artifactId>-->
<!--<version>4.5.1.21328</version>-->
<!--<classifier>10</classifier>-->
<!--<type>2.swc</type>-->
<!--</dependency>-->
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>playerglobal</artifactId>
<version>3.2.0.3958</version>
<classifier>9</classifier>
<type>swc</type>
</dependency>
</dependencies>
</project>
Things I have tried:
1. I have added the required dependency of artifact playerglobal as seen in above pom.xml file, and I have tried with 3 different versions of it (seen above in pom). However, none of them helps.
2. I have tried adding playerglobal dependency inside the 'plugin' node, and also inside the common 'dependencies' node separately in pom. However, any of them are not helping. [Reason to try both these things is that for other couple of dependencies of flex-compiler-oem and mxmlc, it was not recognizing required classes when the dependencies were added just in the common 'dependencies' node. When I added them inside the 'plugin dependencies', then it moved on from those errors.]
3. As per this article, I have also tried keeping the 'com.adobe.flex > compiler' right after 'configuration' node. However, that also doesn't help.
4. I am using Maven 3.2.5 right now, but I have tried with various other maven versions like 3.3.9, 3.0.5, 3.1.1 too. They are also not helping. (3.3.9 is not supported for flexmojos-maven-plugin 7.1.0 as per this article. It also says that maven 3.2.5 is working fine though. Using maven 3.0.5 says that minimum required maven version is 3.1.1. And using maven 3.1.1 gives same error as I am getting right now with maven 3.2.5.)
My SDK/IDE versions:
Maven: 3.2.5
Flex: 3.2.0
JDK: 1.8
IntelliJ IDEA: Ultimate 2017.1
Any help would be greatly appreciated. Thanks in advance.
I don't know to what extent you’re familiar with using Flex in the Maven world, but there were many discussions on what to do with Flex in a post-Flash world (I haven’t had to deal with setting up and maintaining Flex Maven-based projects in about 5-6 years now). Basically, Adobe didn’t want to publish their artifacts to Maven Central, they used to have their own repositories. Then Adobe disowned their Flex project and contributed it to Apache (if I recall correctly, not all of it, but most of it). The guys at Apache re-worked things to a large extent and have been the ones developing it now.
To be honest, I haven’t followed up on Flex over the years, as I think there is no point in using it anymore, as with HTML5, Flex seems as an obsolete technology. The world is no longer using Flash and this has brought a lot benefits to everyone. However, this is just my opinion and I’m not a UI expert.
The guys at Apache decided not to reset the versions and continue where Adobe left – just the artifact coordinates were changed. The groupId-s are now org.apache.flex* (you can check the Apache Flex dependencies published here), instead of com.apache.*. These artifacts are now available via Maven Central. You should switch to a newer version of Maven and use at least 3.3.9.
For more on the history of the project (which is actually quite important, if you’d like to get a better understanding of the dependency mess and what’s now a point of truth and what’s not, please check here and here). The Flex documentation is now on the Apache site. This page is perhaps the most recent and detailed one that I could find, although I’m not 100% sure it’s up-to-date.
You will have to do some further reading up and investigation, but based on your example above, it looks like you're using very, very old versions of the Flex libraries. I would recommend using Maven Central's search engine and searching for each of the artifactId-s and replacing them with the most recent ones and seeing how that goes...
Good luck! :)
I have addressed above issue now. I came across some links which talked about mavenizing the Flex SDK, such as this and this. The second link is the one suggested by carlspring in his above answer; however, I could not follow its steps fully since the git URL mentioned in it is blocked in my company network. So I downloaded the code from the former link and created the mavenizer, and executed it as per the steps given in the link to generate the mavenized SDK. (I faced an issue in the mavenizer where the connection to external maven repository is done to check for updates, so I commented that code and created mavenized SDK successfully after that.)
After generating the Mavenized SDK, you just have to copy it in your local maven repository, and then the playerglobal/airglobal dependencies will successfully get resolved.
Note: In addition to the first link mentioned above, refer to this link as well, which has more detailed steps of mavenizing the Flex SDK. It helped me a lot in creating the folder structure properly.

Using different JBoss BOM in profiles

I have a general question about the usage of the BOM from JBoss and WildFly.
Is the a way to build a project for both JBoss 7 and WildFly 10 using a different profile?
I tried to copy the BOM definition from WildFly into a profile like this:
<profile>
<id>WildFly10</id>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-javaee7-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- JSON -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${version.json}</version>
</dependency>
</dependencies>
</dependencyManagement>
</profile>
Of course accourdingly with a JBoss7 profile.
But this way it won't add important libraries to the lib folder, i.e. this definition is in an ear pom and a subproject (war) adds the json dependency. Without a profile maven adds the json jar inside the lib folder, but not if I put it inside a profile.
After I read that changing dependencies in a profile is an anti-pattern [1] I would like to know how I can build my project for both JBoss7 and WildFly 10.
Update
Ok sorry for this quick shot of a question. Here are more details.
project structure:
|-parent (pom)
|- myapp (war)
|- core (jar)
|- deployment (ear)
So deployment is the project building the whole ear containing myapp as a web apllication and core as a library. myapp has a dependency to core and core to json.
In order to have all needed depenedencies with the correct version I included wildfly-javaee7-with-tools in the dependencyManagment. Also is the version of json defined in there. The core project has the json library as a normal dependency.
At this point this should be quite standard. But the thing is I want to be able to build for JBoss 7 and WildFly 10, for what I have to change
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-javaee7-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
to
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Of course ${version.jboss.bom} will be changed from 10.1.0.Final for WildFly to 1.0.7.Final for JBoss.
In order to do so I tried to move wildfly-javaee7-with-tools into a profile. My first guess was to only move this dependency to a profile. But then the json jar doesn't get included. After that I also tried to move jsonlike above.
Without seeing the original not-profiled nor profiled pom in whole cannot say anything accurate but educated guess.
You have json in profiles dependency management.
Is it also in poms main dependencies without version? If not it will not be copied to lib nor packed. It is only managed by profiles <dependencyManagement>.
Does json need managing per profile? It seems to have ${version.json} which then anyway would be same for each profile if copied as it is in the example.
For me it seems that fix might be that you remove the json from profiles dependencyManagement and add it to main dependencies as normal dependency - this just to make profiling more simple - it can be managed but if not needed set the version of json directly to dependency.

Why order of Maven dependencies matter?

I thought that the order of Maven dependencies doesn't matter before and regard this as a pro of it. And this is my old pom.xml's dependencies:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
It works well, and today I wanna move spring dependency to the bottom so that those jersey related can be together. However then I can no longer make it working, my Jetty complains:
[ERROR] Failed to execute goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run (default-cli) on project mtest: Execution default-cli of goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run failed: A required class was missing while executing org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run: org/apache/commons/logging/LogFactory
That is really confusing, so do I have to concern about dependencies order? How do I know the correct order?
The order of dependencies does matter because of how Maven resolves transitive dependencies, starting with version 2.0.9. Excerpt from the documentation:
(...) this determines what version of a dependency will be used when multiple versions of an artifact are encountered. (...) You can always guarantee a version by declaring it explicitly in your project's POM. (...) since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
To expand upon the other answer (which states that the declaration order affects Maven's dependency mediation for transitive dependencies), there are a few tools you can use:
mvn dependency:tree [-Dscope=[runtime|test]] will show you what dependencies will be available for the selected scope. See here for details
mvn dependency:build-classpath gives you order in which dependencies are available on your classpath (if two or more classpath entries have the same class, the earlier one wins). See here for details
I don't know much about your situation, but it's often the case that you wind up with the wrong version of 1 or more jars at compile/runtime. Declaring your own version of the library in question or locking down the version with <dependencyManagement> are options here.
Now to answer your other question - how do you know what the right order is when declaring dependencies?
My suggestion - the right declaration order is the one that gets you the versions of the dependencies you want, in the order you want them in. Use the tools above to check your dependencies, and tweak the declared order if necessary.
Note that most jars contain disjointedly-named classes, so the exact order in which jars appear on your classpath is usually not that important. The only exception I've noticed is some jars in SLF4J which intentionally shadow classes from the other logger libraries it's intended to replace.

The right way to use maven

I'm new to maven, I got 2 problems here:
1,How to solve missing artifact problem?
I need jcharts-0.7.5, but it's not available in Maven Central Repository. I have the jar file, but seems not easy to put it into a maven project.
2,How to fix wrong dependency scope of artifact?
I have a WAR project depends on artifact axis2-kernel, which is depending on servlet-api-2.3 with the scope of 'compile' (mistake of 'provided'), so mvn install packet the servlet-api-2.3.jar into the war file, and causes a "validateJarFile(...) - jar not loaded." error in Tomcat 7.
Number one: use a maven repository. This can be a simple Apache HTTP site with static content. But I would recommend using Sonatype Nexus or JFrog Artifactory for storing artifacts not found somewhere else.
You may find them in the JBoss repository or IBiblio (both quite big)
Number two: you can add that dependency to your pom and just set the scope you want. If you exclude the artifact you will have to add it again anyway. Maven will always prefer what is directly in you pom:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
To answer your second question: you can exclude transitive dependencies using the < exclusion > tag: http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
<project>
...
<dependencies>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>...</version>
<exclusions>
<exclusion><!-- declare the exclusion here -->
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
There are many different solutions how to add missing dependencies. For example, you could use the scope system and provide the path (you can put the JAR into the project and use a path relative to ${basedir}).
But a much better solution is to install a server like Nexus or Artifactory because they allow you to create your own repositories and they still work should the Internet fail (for example, when some idiot breaks your router or your ISP has some problems or someone drives a 18 inch double-T steel beam through a bunch of fibres).
Builds will also be much faster since the downloads will be via your local LAN instead of going around half the globe.
You can simply repeat the dependency in your POM with a different scope (your POM always wins) or you can use a dependencyManagement element.
I prefer the dependencyManagement approach because it allows you to set scopes and versions in a single place for all your projects.

downloading guice3.0 artifact from maven central repository

I'm trying to upgrade my struts2 web app from guice2.0 to guice3.0.
I'm trying to test it out using maven jetty.
I've successfully upgraded my pom.xml to use the correct version and groupId for the 3.0 release, but if I call mvn jetty:run
I see that it is trying to download
guice-3.0-no_deps.jar
which throws a build error and can't be found the central repository?
I don't get this error if I don't include any guice extensions.
Any ideas?
Thanks
I posted this question also to the guice user group.
This is the answer I received.
The guice-3.0-no_deps.jar is a build-time artifact that's used to compile the extensions, but is not required at runtime - it's not on maven central because the Guice team didn't want people depending on this "uber-jar" by mistake. The extensions have an optional dependency to guice-3.0-no_deps.jar (so they can compile) but they also have a non-optional dependency to guice-3.0.jar for the runtime case.
Well-behaved maven plugins should see that the the no_deps dependency is optional and not throw a build error if it's missing, so this sounds like a bug in the jetty plugin. To workaround the Jetty bug you can explicitly hide this dependency as follows:
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-struts2</artifactId>
<version>3.0</version>
<exclusions>
<exclusion>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
</dependency>
Note that we can't do this in the original build pom because we still need the no_deps dependency when doing the original compilation.

Resources