Eclipse not publishing web.xml filled by Maven - eclipse

Continuing my prior question (Maven: how to fill a variable in web.xml file), I realized that the values written in web.xml are not passed to the deployed web.xml.
Let me show what is happening: I am running a web application in Tomcat through WTP Eclipse. In the web.xml, I have this context-param:
<context-param>
<param-name>producao</param-name>
<param-value>${ambiente.producao}</param-value>
</context-param>
The ambiente.producao is filled according to Maven profile chosen:
<profiles>
<profile>
<id>prod</id>
<properties>
<ambiente.producao>true</ambiente.producao>
</properties>
</profile>
<profile>
<id>desenv</id>
<properties>
<ambiente.producao>false</ambiente.producao>
</properties>
</profile>
</profiles>
Also, I have a ServletContextListener implementation which will print the value of the producao param:
public void contextInitialized(ServletContextEvent event) {
logger.warn(event.getServletContext().getInitParameter("producao"));
}
Thanks to Fred Bricon tip, I was able make the Maven fill correctly the ambiente.producao variable in the web.xml copied to the target directory.
However, when I start the Tomcat and print the the producao init param, It is showed ${ambiente.producao}. Actually, when I open the web.xml present in the directory [WORKSPACE_DIR]/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/sinpo-web/WEB-INF, the producao is not filled as it should be. It was like Eclipse (or WTP or Maven) had chosen the original file instead of filled file.
Therefore, I ask if there is some missing configuration needed to make the Maven (or Eclipse) publish using the files in target directory instead the original file.
Thanks,
Rafael Afonso

Related

Spring MVC with Spring Boot doesn't work with the Tomcat server of Eclipse

I tried to follow Spring Getting Started Guide for "Serving Web Content with Spring MVC" which uses Spring Boot and Gradle in addition to Maven.
I installed Gradle plugins to Eclipse.
I want to run the application using the Tomcat server in Eclipse because of that I also followed "Converting a Spring Boot JAR Application to a WAR" guide and changed the "build.gradle" file as mentioned in the guide. Basically, I added lines "apply plugin: 'eclipse-wtp'", "apply plugin: 'war'", configurations {providedRuntime}, and providedRuntime("org.springframework.boot:spring-boot-starter-tomcat"); and changed jar settings to war settings. Here is the build.gradle file:
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-milestone" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.2.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
eclipse.project {
natures 'org.springsource.ide.eclipse.gradle.core.nature'
}
war {
baseName = 'gs-serving-web-content'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-milestone" }
}
configurations {
providedRuntime
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
testCompile("junit:junit")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
I also added HelloWebXml class as they mention. Here is the class:
package hello;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class HelloWebXml extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
In addition to these I needed to change pom.xml a little because it was complaining about Java SE 7 features. Added the lines below to the pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<showWarnings>true</showWarnings>
<compilerVersion>1.7</compilerVersion>
<fork>true</fork>
</configuration>
</plugin>
The rest is the same as the getting started guide.
For building, I run
gradlew eclipseWtp
gradlew clean build
commands. After this the war file is created in build/libs folder of the project. If I copy the war file to my local Tomcat server and start the server, everything works as expected.
If I drag the project to the Tomcat server under the Servers tab (which is created using the same local Tomcat) and run the server, a ClassCastException is thrown with the complaint:
"Cannot cast org.springframework.web.SpringServletContainerInitializer to javax.servlet.ServletContainerInitializer".
I checked the folder structure of the project in both of the deployment locations.
In the local (non-Eclipse) deployment location, after the server starts a folder with the name of the war file is created as expected. In the WEB-INF folder, there is a lib-provided directory. I checked the deployment location of the Tomcat of Eclipse, it didn't include a directory named lib-provided. I guess the problem is about this directory not being created but I couldn't find a solution.
I was already using Spring MVC, and I know how to create MVC projects with web.xml but I am new to Spring Boot. The Tomcat server of Eclipse runs my previous Spring MVC projects fine. So the problem is about the Spring Boot project.
I checked several related questions but they were not the same one as mine. I couldn't find a solution to my problem.
What am I missing here?
Thanks in advance.
I imagine that you are getting a clash with the servlet-api JARs. If you are developing with embedded Tomcat (creating a JAR) you need to include the servlet-api JAR on your classpath in the compile scope. When you are deploying to an existing Tomcat installation (creating a WAR) you must declare the servlet-api jar in provided scope, otherwise it will end up in web-inf/lib and cause conflicts with the version provided by your container.
Here is the POM from the sample Spring Boot WAR project:
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-traditional/pom.xml
Note how the spring-boot-starter-tomcat uses the provided scope.
Spring Boot does some special handling to allow executable WARs that run both embedded or in a container. Specific attention has to be payed to dependencies in provided scope since these might conflict with the container. The details are described in the Spring Boot reference guide. The reason your build works when deployed via a built WAR but not via Eclipse is that Eclipse WTP doesn't actually use Maven to perform the build, so a Maven build and a WTP build won't exactly match.
I'm working on addressing the same issue myself. What I plan to do is create a seperate 'dev' maven module specifically for this purpose, and use tags to switch (some of) the provided entries to runtime.
#meribald you can configure your pom.xml in that whay:
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging-profile>jar</packaging-profile>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>prod</id>
<properties>
<packaging-profile>war</packaging-profile>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
and on the top of your pom.xml
<packaging>${packaging-profile}</packaging>
So, when you are developing you run you application as a Java Application, and maven will generate a jar file. When you want to package a war file to deploy on a server, you run on a maven command line
mvn -Pprod package
or in Eclipse run as >> Maven Build ..., and put "package" on the goals field, and "prod" (without quotes) on profiles field.

Using Maven's .m2/settings.xml throws warning in Eclipse m2e

I'm using Maven's settings.xml to override a property value for a log4j.properties file for development purposes. However, after I made this change, I now receive warnings in Eclipse m2e even though this is a normal use case:
Access "/Users/junger/.m2" directory outside of project base
directory.
(org.apache.maven.plugins:maven-resources-plugin:2.5:resources:default-resources:process-resources)
How do I remove this warning? Or, is there a bug tracking this? I couldn't find one.
In my pom.xml, I have -
<properties>
<log4j.properties.directory>src/main/java</log4j.properties.directory>
</properties>
In my settings.xml, I have -
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.properties.directory>/Users/junger/.m2/</log4j.properties.directory>
</properties>
</profile>
</profiles>
Looking at the code (the newScanner() method) of m2e, this seems to be an explicit warning when your project references files outside of its base directory.
For me, this warning is kind of justified. When you are referencing resources outside of your project's basedir, your builds might not be reproducible anymore. Your projects should rather be self contained without depending on external files.

Change a file xml with maven plugin

I´m working with maven 3, migrating the old application using hivemind and ant. I need to change The file "Hivemodule.xml" with some properties with information about enviroment, I define with profile but it doesn´t work.
I try using maven-resources-plugin but without success, perhaps it just do with properties files.
Detail: The Hivemodule.xml is inside the file jar and I want to unpack this file to turn the content of internal hivemodule configurations and after, to pack again... I´m in the unpack fase.
Here is my file in Hivemodule.xml and the parameters that I want to turn:
PROVIDER_URL="ormi://localhost:23791/"
APPLICATION_NAME="services_1_11"
SECURITY_PRINCIPAL="oc4jadmin"
SECURITY_CREDENTIAL="welcome"
For use of profiles, I edited this file:
PROVIDER_URL="${PROVIDER_URL}"
APPLICATION_NAME="${APPLICATION_NAME}"
SECURITY_PRINCIPAL="${SECURITY_PRINCIPAL}"
SECURITY_CREDENTIAL="${SECURITY_CREDENTIAL}"
In my pom.xml, the references to profile:
<profiles>
<profile>
<id>local</id>
<properties>
<PROVIDER_URL>ormi://localhost:23791/</PROVIDER_URL>
<APPLICATION_NAME>services_1_11</APPLICATION_NAME>
<SECURITY_PRINCIPAL>oc4jadmin</SECURITY_PRINCIPAL>
<SECURITY_CREDENTIAL>welcome</SECURITY_CREDENTIAL>
</properties>
</profile>
</profiles>
And my resource configurations:
<resources>
<resource>
<directory>${serviceSegPath}/${serviceName}/META-INF/</directory>
<filtering>true</filtering>
</resource>
</resources>
Is there any suggestion to solution this? Another plugin to make changes in xml file?
Perhaps this profile is not active when running maven.
mvn -P local clean install

Maven assembly plugin: run only one descriptor

I have a project which has several custom descriptors written for the assembly plugin. Is there a way to run only one of those descriptors at a time instead of the whole bunch? I tried using the descriptors switch as documented here, passing in the full path to the one descriptor that I wanted to run, but instead it's running all of the descriptors in my app's main pom file, seeming to ignore the switch I specified.
Probably the easiest way to do so, is by using Maven Profiles.
Define some profiles in your pom.xml:
<profiles>
<profile>
<id>profile-1</id>
<properties>
<assembly-config>assem1.xml</assembly-config>
</properties>
</profile>
<profile>
<id>profile-2</id>
<properties>
<assembly-config>assem2.xml</assembly-config>
</properties>
</profile>
</profiles>
Then you use that particular property for the configuration of the assembly plugin:
...
<descriptor>src/main/assembly/${assembly-config}</descriptor>
...
Then run your maven build with the -P option: mvn -P profile-1 compile
So, summarized, if you choose a profile at buildtime, the property assembly-config will be set depending on the defined profile. The assembly configuration depends in that case on the chosen profile.
Hope this helps!

Porting a tomcat web project from eclipse ganymede to intellij 8.1

I have a standard (I think) web project developed with the eclipse IDE. I wish to port it to Intellij idea 8.1 - I think that, among other things, it has better taglib support.
My project structure is as follows:
Project Folder
./src [java source files etc.]
./conf [configuration files - log4j, spring beans...]
./buid [ant files]
./WebContent
./WebContent/images [image files]
./WebContent/META-INF
./WebContent/META-INF/context.xml
./WebContent/pages [.jsp+.html files]
./WebContent/scripts [.js files]
./WebContent/skins [.css files]
./WebContent/WEB-INF
./WebContent/WEB-INF/classes [.class files]
./WebContent/WEB-INF/lib [.jar files]
./WebContent/WEB-INF/tags [.tag files]
./WebContent/WEB-INF/web.xml
I can't seem to get this project configured with my local tomcat server (version: apache-tomcat-6.0.18).
I think that a good answer would be a standard, step by step, cookbook answer as to how to port (and perhaps how to correctly define a tomcat web application within intellij idea).
Thanks all!
I think the first step would be to create a stand-alone build file which will produce a WAR. Do this before attempting to import the project into InteliJ.
I would use Maven. Creating a maven POM file to create a WAR is almost trivial and you can easily override the the default locations for your src, conf, and web content to match you existing src directory. Then test the build by deploying your newly Maven created WAR to Tomcat. I wouldn't think this first task would take more than a half day (at most a full day).
IntelliJ has a built in utility to import Maven projects. Then you should be off and running....
Regardless of the IDE you finally settle on, your project will be much better off in the long run for the Maven migration.
You initial Maven POM file will look something like this...
<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>com.yourcompany.yourapp</groupId>
<artifactId>yourapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Your project name here</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
*** other dependencies here ***
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>conf</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>WebContent</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
*** This is an example POM only... It's just meant to get you started and may not work "as is".
Start off by creating an empty web application for tomcat, within IntelliJ - and make sure that it deploys correctly
This will produce a directory structure that you should then be able to copy your source files/web assets into.
The thing that you'll probably need to handle differently is the lib files - don't store these directly in the WEB-INF directory, as keeping them in a separate 'library' area, and allowing the IDE to include them in the WAR at build time is generally a better approach, as it promotes re-use across projects.
The key thing to aim for is to not try to set your project up to completely mirror a tomcat application, as the build process will pull together the various parts for you. It all breaks down into 3 sections...
Static assets - images, config files and jsp files (Ok, I know JSP files are kinda dynamic)
Java classes - source code that you write yourself (The IDE will compile these and place them in the appropriate location)
Java Libraries - third party code that you compile against (Again the IDE will place these in the appropriate location)
There are a few bits of configuration, within the project file, that you'll need to tweak to suit your needs, but it's generally straightforward.
By default, log4j will look for it's configuration file (either log4j.xml or log4j.properties) from the classpath of your application. So this means you should place it in WEB-INF\classes, or you can specify a different location with the environment variable log4j.configuration. See the log4j manual.
What IDE you use should have no impact on the structure of your application when it gets deployed to your servlet container. It sounds like maybe you were relying on Eclipse to package the files in a specific way - this is probably a bad practice. Are you using an actual build script?