Maven Tomcat7 run a dependency war - java

I have a question regarding maven and its tomcat7 plugin :)
I have the following maven projects:
plugin1: plain java project packaged as jar
plugin2: plain java project packaged as jar
webapp: standalone webapp project packaged as jar
those three project are properly build in maven and the outcome works fine:
I can use the jars from plugin1/plugin2
I can deploy the webapp war file to a web container
I can run tomcat7:run to start the webapp
Now, I need to provide different packaging of the webapp containing specific plugin setup.
i.e. I want to generate a war file with webapp + plugin1 and another one with webapp + pugin2
To achieve this, I have created 2 additionnal maven projects that declare dependancies on the webapp project + the appropriate plugin projects and are packaged as wars.
The generated war files have the expected content, and can be deployed to a tomcat, but when I try to use the maven tomcat plugin (tomcat7:run again), it simply doesnt start anything.
Though this is not blocking for me (my main point was to generate the war files), I have the feeling that I missed something.
the pom.xml for those aggregate projects looks like this (note that there is absolutly no code in those projects, these were just created for packaging with specific dependancies convenience).
<groupId>my.project</groupId>
<artifactId>live1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>MyWebapp</name>
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>my.project</groupId>
<artifactId>plugin1</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>my.project</groupId>
<artifactId>webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>MyWebapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<url>http://localhost:8080/manager</url>
<server>localhost</server>
<path>/${project.build.finalName}</path>
</configuration>
</plugin>
</plugins>
</build>
Thanks !
note: long time lurker, first time asker here, if some information is missing tell me :)

Depending on the structure of your project it may not be suficient to just add a dependency of type war. You may need also to configure <overlays> as described here maven-war-plugin.
It looks like your final war does not provide the full web configuration that you expect. With overlays you can configure how the resources from the dependency will be packed into your final web app.
There must be some difference in the way that your external tomcat starts the app compared to the tomcat7 plugin. May be you can try -X option :
mvn -X tomcat7:run
This should log out some details, of what the embedded tomcat is configuring..

Related

Liferay 7.3 war deployment takes to long for development

I'm trying to setup a development ambient using Liferay (7.3) DevStudio in Eclipse, where I have a liferay module which was/is a Maven webapp project ( deployed in the past to IBM Websphere Portal ). Everything works well, I can open liferay portal and access my webapp application.
The problem I have is that this app is more or less 80mb with a tone of files already and every time I do a change in java files or any other files, after compilation of the project ( which is fast btw ) it begins the process of deployment do the internal tomcat of liferay bundle.
On deployment it is created a war file package (based on maven packaging option[war]) and copied by liferay to the deploy folder of the internal tomcat and this takes to long...
My objective is to alter anything from project structure ( liferay or module ), pom.xml to allow me to run the project while on development, every time I do a change I don´t want to deploy the war in this fashion. I want only to tomcat assume the changed filed and not the complete app...
What am I missing here? Can I do some hot deploy or something in tomcat? I mean develop with the exploded project inside tomcat?
I hope you understand and feel free to ask for any detail you need to formulate an answer...
So sorry for the long text... Here is the project structure, pom.xml and system.out log
pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>something.company</groupId>
<artifactId>MyProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
</properties>
<build>
<finalName>MyProject</finalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>MyProject</warName>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<configuration>
<files>
<file>${project.basedir}/src/main/webapp/WEB-INF/classes/version/build-version.properties</file>
</files>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>portal-service</artifactId>
<version>6.2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>com.liferay.portal.kernel</artifactId>
<version>9.8.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>com.liferay.util.bridges</artifactId>
<version>7.0.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>com.liferay.util.taglib</artifactId>
<version>5.2.5</version>
<scope>provided</scope>
</dependency>
...other project dependencies not relevant
</dependencies>
</project>
This is the look of project structure in Eclipse:
Console log starting ok building war
This is where it takes to long...deploying the war file. I don´t want to deploy the war file I want to develop with the project exploded in tomcat so that when I change a few files I only want these changes to be assumed.
You're deploying an 80MB artifact - I assume that it largely is 80MB because of the dependencies that you labelled as "irrelevant" in the pom.xml above.
These dependencies - even if unchanged - need to be analyzed (which means: unpacked, parsed, processed) upon deployment. Liferay transforms a WAR file into an OSGi bundle - and if you want to accellerate that process, you can do the same, before the actual deployment: The easiest way, with the most control on your end, would be if you transform your plugin into an OSGi bundle yourself.
In case your dependencies are already OSGi bundles, you deploy them once, and any update to your own component will be an update to a tiny component (now that the dependencies are out of it). Otherwise, OGSi'ify them, and you'll save yourself from redeployment.
You can also split your single monolithic plugin into multiple smaller bundles, cutting down even further and easing maintainability and improving architectural independence of various parts of your own plugin.

"Cannot resolve symbol" when trying to import classes from a jar deployed in my custom maven nexus repo

It's not my first time reading deployed jars from my custom maven nexus repo (my setting.xml is correctly written ), but unfortunately, this time I wasn't able to import classes from a new deployed spring-boot jar, although it does exist in the project classpath.
Cannot resolve symbol 'test'
ps: the jar code snippet in my pom.xml is as below
<project>
...
<dependency>
<groupId>cc.test</groupId>
<artifactId>jar-name</artifactId>
<version>0.1.4</version>
</dependency>
....
</project>
Quick update:
After trying almost everything, I found the solution!
Shortly a Spring Boot application is not intended to be used as a dependency, thus adding the below configs will generate two separate jars, your application’s executable fat jar will be published with an exec classifier. The normal jar that can be used as a dependency will be unclassified. this unclassified jar will be deployed in your maven nexus repo, and used as a maven dependency in another spring-boot project
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
My response is based on spring-boot official documentation:
https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#howto-create-an-additional-executable-jar

Maven packaging for websphere

I am trying to build an EAR file - Which can be deployed in IBM websphere server.
This is an existing struts appliation, i am trying to mavenize it.
This project contains two folders
1. web
2. webEAR
web is actually for war file and webEAR folder for the EAR file, web contains all the code, and webEAR is a kind of a wrapper.
Steps I have already done are below
IDE - Eclipse
Java version - 1.7
Convereted both web and webEAR to Maven - (Configure to Maven)
edited the POM.XML like below
<modelVersion>4.0.0</modelVersion>
<groupId>com.comp.web</groupId>
<artifactId>web</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<name>WEB</name>
<description>WEB</description>
added all relevant jar files - which are in lib folder as below (sample)
<dependency>
<groupId>jarfile</groupId>
<artifactId>com.ibm.jar</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/WebContent/WEBINF/lib/com.ibm.jarfile.jar</systemPat>
</dependency>
Now i dont have any errors in the eclipse, and I can run the application by right clicking the webEAR folder -> Run in Server, It works.
but I am not sure, how to create a EAR file , which has the war file, so that I can deploy in the WAS server dev environment.
Can someone show me a way I can do this. currently there is no POM.xml in the webEAR maven folder
P.S - I am not a Java developer. This is a first maven related project I am assigned to. I appreciate any help
Your module should have <packaging>ear</packaging>.
In the dependencies for this ear module ( Use a new module to build the ear ) include your war module as below.
<dependency>
<groupId>com.comp.webGroupId</groupId>
<artifactId>war-artifact</artifactId>
<version> war-version</version>
<type>war</type>
</dependency>
In the build plugins for this ear module include the maven-ear-plugin.
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<finalName>web</finalName>
<version>versionNumber</version>
<generatedDescriptorLocation>${basedir}/src/main/application/META-INF</generatedDescriptorLocation>
<modules>
<webModule>
<groupId>com.comp.webGroupId</groupId>
<artifactId>war-artifact</artifactId>
<uri>web.war</uri>
<bundleFileName>web.war</bundleFileName>
<contextRoot>/applicationName</contextRoot>
</webModule>
</modules>
</configuration>
</plugin>
Add any specific configuration values as required.

Generated .ear.xml for Liberty in Eclipse is wrong

Problematic plugin
I have an issue with the eclipse Liberty plugin which is available here on the marketplace. I linked the beta, but the behaviour with stable is exaclty the same.
Maven ear project description
I have a maven project which consists of multiple maven modules. The ear module's pom.xml looks like this. By the way, the maven generated ear looks just fine.
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>myear</artifactId>
<packaging>ear</packaging>
<name>my ear module</name>
<dependencies>
<dependency>
<groupId>my.groupid</groupId>
<artifactId>myWARmodule</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>compile</scope>
<!-- EJBs are not to be included in the war. -->
<exclusion>
<groupId>my.groupid</groupId>
<artifactId>myEJBmodule</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>my.groupid</groupId>
<artifactId>myWARmodule</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
<exclusions>
<exclusion>
<groupId>my.groupid</groupId>
<artifactId>myEJBmodule</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- jar module -->
<dependency>
<groupId>my.groupid</groupId>
<artifactId>myAdditionalJarModule</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
<!-- EJB module -->
<dependency>
<groupId>my.groupid</groupId>
<artifactId>myEJBmodule</artifactId>
<type>ejb</type>
</dependency>
<!-- API implementation -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.jsr107.ri</groupId>
<artifactId>cache-annotations-ri-cdi</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>myEarApp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<version>7</version>
<finalName>myEARApp</finalName>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<defaultJavaBundleDir>lib</defaultJavaBundleDir>
<skinnyWars>true</skinnyWars>
<modules>
<!-- Root level modules: WAR and EJBs. -->
<webModule>
<groupId>my.groupd</groupId>
<artifactId>myWARmodule</artifactId>
</webModule>
<ejbModule>
<groupId>my.groupid</groupId>
<artifactId>myEJBmodule</artifactId>
</ejbModule>
<jarModule>
<groupId>my.groupid</groupId>
<artifactId>myAdditionalJarModule</artifactId>
<includeInApplicationXml>true</includeInApplicationXml>
</jarModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
</project>
Resulting ear
The resulting ear file is structured like this:
myEARApp.ear
- myWarApp.war
-- (no libs in WEB-INF/lib)
- lib/
-- (a lot of libs here due to skinny wars)
- myEJBmodule.jar
- myAdditionalJarModule.jar
Properties - Maven assembly descriptor
When I click the ear project and look at "assembly descriptor", the assembly matches the layout of the ear file, which correct.
So, this is fine.
Creating a liberty server and adding the application
Now, when I add in eclipse a server and want to run the ear file, I create a "websphere liberty profile server", version 17.0.0.2. I then add the ear module to the server, configure the application (i.e. application bindings etc.).
The server can run the project from workspace by generating a replacement myEARApp.ear.xml file in the server/apps folder. It has the structure of the ear file. Well, it should have. Since two weeks or so, the structure of the myEARApp.ear.xml-file is more like this:
myEARApp.ear
- myWarApp.war
-- a lot of libs from the war module
-- myEJBmodule.jar
-- myAdditionalJarModule.jar
- lib/
-- only a few extra jar modules referenced in ear/pom.xml
-- missing: logback, ehcache, etc.
- myEJBmodule.jar
- myAdditionalJarModule.jar
- otherDependencyOfmyAdditionalJarModule.jar
The bad thing is that this obivously won't run due to duplicate beans available for injection and a lot classnotfoundexceptions.
How to solve?
So, my question is: How does the eclipse liberty profile plugin generate it's .ear.xml-file? Why does it differ from the layout I configured in the pom.xml? Even without skinny wars and the import scope dependency, the generated myEARApp.ear.xml file for liberty won't change.
Help appreciated!
found the solution.
I removed a lot of jboss plugins from eclipse, like JBoss developer tools, JBoss Hibernate, etc.
I just kept a few:
CDI tools
Java EE Batch Config Tools
JMX Console
M2E connector for Eclipse JDT Compiler
Maven Integration for Eclipse JDT APT
Now it works just fine again. Who would have thought that? Also, it didn't appear in any log why the generation of the .ear.xml file for liberty was corrupted by JBoss Dev Studio or other plugins.
I hope this is useful to any other developers.
WDT generates the myEARApp.ear.xml file based on the deployment assembly settings in the project properties. When the project is imported into the workspace, the Eclipse M2E plugin is supposed to interpret the pom.xml and translate the settings and setup the deployment assembly in the project properties based on the settings in the pom.xml file.
Can you check the Deployment Assembly page in the project properties of the EAR and Web modules to see if the module is being setup properly as you would expect? The other thing that you can try is to export the EAR file (using the Export menu when you right click on the EAR project). If the exported project does not have the structure that you expect, then the problem is caused by the Eclipse M2E plugin does not support skinnyWars properly as mentioned in the bugzilla on the earlier comment.
Looks like Eclipse M2E plugin doesn't support skinnyWars. You can try the work around at the bottom of the bug report.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=461613

Customised maven deployable (war with some dependencies removed)

I have a multi module web app building with maven. We build the war as per normal and deploy and run on developer machines and local test servers using tomcat.
Then we want to deploy the application to the cloud. To do this we create a special version of tomcat which has all the libraries preloaded and a special version of the war which only has our code. Point here is tomcat is preloaded on the cloud server, the war is uploaded each time it is changed. Currently we are having to manually remove the dependencies from the built war.
What is the best way for maven to do this? Should I build a custom packaging type or maybe run some post build plugin to remove these wars? Or something else? I think the best way to activate this custom build is via a profile. I did try and remove these dependencies by setting them to scope = provided in the new profile but the transitive dependencies still made it into the war.
If you want to exclude all dependencies, you can use the war plugin's packagingExcludes to do so:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
...
</configuration>
</plugin>
Specify this plugin inside a profile to only perform it for production.
You can achieve using profile in maven. As you said it is not working, I can think of you configure something wrong. Try something like:
<profiles>
<profile>
<id>dev</id>
<activation>
<!-- active by default, turn off when on prod -->
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<!-- include this in dev, not in prod -->
<dependency>
<groupId>com.company</groupId>
<artifactId>xyz</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
Then in command line, mvn package -P !dev to deactivate dev profile so that not include the jars.
Make sure com.company:xzy is not included in <project><dependencies></dependencies></project>.

Categories

Resources