Kick off Spring Boot & make a call using a maven profile - maven

I have an existing application which is a jetty app written in Java and managed with maven. There are a few basic tasks that can be run from the browser but mainly it runs all the tasks in one go when run from the command line (or Jenkins).
It does this by calling a specific Maven profile
so the maven command line call is
mvn clean install -P autorun
The autorun profile is
<profile>
<id>autorun</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<property name="runtime_classpath" refid="maven.runtime.classpath"/>
<java classname="com.app.tool.Client" >
<arg value="-h" />
<classpath>
<pathelement path="${runtime_classpath}"/>
</classpath>
</java>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
there is a main procedure in the Client class
public static void main(String... args) throws Exception { ...
which essentially
creates an org.eclipse.jetty.server.Server object
uses the war file to kick off the http server app
Uses a number of org.springframework.http.client.ClientHttpRequest objects to fire off a number of tasks using code along the lines of
ClientHttpRequest request = restTemplate
.getRequestFactory()
.createRequest(
new URI("http://localhost:8080/tool/spring/" + jobName),
HttpMethod.GET);
ClientHttpResponse clientHttpResponse = request.execute();
if (clientHttpResponse.getStatusCode().value() != HttpStatus.OK_200) {
throw new RuntimeException(...);
}
I am going to refactor the app now for various reasons. My aim is to keep the current design as, although it's main current use points more to a console app, I would like to make add some more useful interactive functionality.
So to finally get to the point, I have started re-writing the app as a Spring Boot application. I would like to still be able to fire off the jobs I want from the command line (and Jenkins). Is there a simple (& equivalent) way to do this with Spring Boot & Maven ? I am using Main to fire off the app so possibly I need to pass a switch into here
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootStartUpConfig.class, args);
}
I'm guessing that a lot of the code currently used to start the server can be dumped but I'm struggling to find the best way to achieve this ? (I'd prefer to use Maven as this is the core tool we are using but I can use Gradle if this is something that it is better at).

To run a spring boot application from command line you could include the spring boot maven plugin see reference here
Spring boot maven plugin
and then launch it from command line using
mvn spring-boot:run

Related

Auto-Restart for Spring Boot Tests

I am currently writing unit and integration tests for a Spring Boot application. I'm using Spring Tool Suites 4 for development.
When I run the application using Spring Tool Suites, the auto-restart works fine when I modify and save a file. I'm trying to find a similar way to run my tests.
I currently run the tests using a separate Windows CMD terminal using Maven:
mvn test
This runs one time and terminates. Is there anyway to have the tests run every time a test file is saved?
Edit: Here's an example of a test I am running that uses JUnit and Spring to run the tests. This is taken straight from the Spring.io website https://spring.io/guides/gs/testing-web/
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
#SpringBootTest
public class ControllerTest {
#Autowired
private Controller controller;
#Test
public void contexLoads() throws Exception {
assertThat(controller).isNotNull();
}
}
I found this Maven plugin https://github.com/fizzed/maven-plugins#watcher-fizzed-watcher-maven-plugin that will watch files and let you run specific Maven goals on file changes.
I added the plugin to my POM and changed the goal to "test".
<build>
<plugins>
<plugin>
<groupId>com.fizzed</groupId>
<artifactId>fizzed-watcher-maven-plugin</artifactId>
<version>1.0.6</version>
<configuration>
<touchFile>target/classes/watcher.txt</touchFile>
<watches>
<watch>
<directory>src/main/java</directory>
</watch>
<watch>
<directory>src/test/java</directory>
</watch>
</watches>
<goals>
<goal>test</goal>
</goals>
</configuration>
</plugin>
<plugins>
<build>
I opened a terminal within Spring Tool Suites (ctrl + alt + t) and docked it next to my console and ran the following:
mvn fizzed-watcher:run
So far this seems to be working exactly like I want.

Is it possible to "clean" deploy Oracle service bus project to OSB using maven?

I need to be sure in clean maven deployment of a project.
I mean not 'mvn clean deploy', but to remove existing project from OSB before deploying (overwriting).
If you overwrite project on OSB, you can't be sure that all of its resources will be updated. I've seen a lot of cases when some resources in project are overwritten and some are not. It's quite unpredictable behavior.
So the question is: is it some maven (maven service bus plugin or maybe some other one like maven weblogic) task or parameter to force update project before deploying?
Well, I found the solution. It is not straightforward. Actually I dont like it, but it works.
The only solution I have found is to delete service (project in OSB terms) from OSB console using WLST.
The working script I found in the Martien van den Akker's blog here: http://blog.darwin-it.nl/2014/03/osb-remove-artefacts-with-wlst.html
It is ready to use script. But this works only for OSB 11 and doesnt work for OSB 12.
So you can use this workaround: http://soamagic.blogspot.com/2016/05/osb-12c-java.html
In my CI server (Hudson-based) I added Maven build step to launch sh-script, which executes wlst.sh with py-script as a parameter (actually there are 4+ parameters - weblogic admin username, password, url and others - project names to delete). This build step executes before every service deploy.
This guarantees that the newest version of the service will be deployed to the OSB-server.
Edit: Not sure if it worth posting, but I hope someone can find something useful in my code. So here it is:
Maven build:
<profile>
<id>undeployService</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>wlst-undeploy-service</id>
<phase>process-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>
${project.basedir}/../conf/WLST/undeployProject.sh
</executable>
<arguments>
<argument>
${weblogic.username}
</argument>
<argument>
${weblogic.password}
</argument>
<argument>
${weblogic.url}
</argument>
<argument>
${project.artifactId}
</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
undeployProject.sh script:
. ${MW_HOME}/osb/tools/configjar/setenv.sh
${MW_HOME}/osb/tools/configjar/wlst.sh ../conf/WLST/undeployProject.py $*

GWT + Maven + Tomcat + JNDI + Eclipse configuration

I've got a project using GWT 2.6.1 + Maven 3.2 + Tomcat 5.5 (yes, I know it's an old one ...) + Eclipse Luna which is using JNDI allowing for external parameters to be configured.
As you might know, the context XML file is located at /conf/Catalina/localhost/myWebApp.xml where myWebApp is the Java web application name.
I am using gwt-maven-plugin for this project (the one from mojo haus) which has the version 2.6.1.
Here is my current configuration :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.6.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<goal>i18n</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see gwt-maven-plugin documentation at codehaus.org -->
<configuration>
<module>xxx.yyy.myModuleName</module>
<runTarget>myWebPage.html</runTarget>
<hostedWebapp>${webappDirectory}</hostedWebapp>
<encoding>UTF-8</encoding>
<failOnError>true</failOnError>
<style>OBF</style>
<i18nMessagesBundle>xxx.yyy.zzz.client.ui.i18n.OlbClientMessages</i18nMessagesBundle>
<extraParam>true</extraParam>
<extraJvmArgs>-Dgwt.compiler.optimizationLevel=9</extraJvmArgs>
<extraJvmArgs>-Xms128M</extraJvmArgs>
<extraJvmArgs>-Xmx1200M</extraJvmArgs>
<extraJvmArgs>-XX:MaxPermSize=768M</extraJvmArgs>
<noServer>true</noServer>
<logLevel>INFO</logLevel>
</configuration>
</plugin>
As you can see, i am using the noServer (configured to "true") option because I must use an external Tomcat container for the server side.
My question is :
How can I enable client side AND server side debugging within my actual configuration through a step-by-step help.
I've made a lot of attempts but i can't make things working.
I've tested running the "mvn gwt-debug" which tries to connect to default port 8000 and then connecting a remote java application which connects to my webapp to localhost:8000 and it works well, but it's only for the server side.
I also need to debug the client side in the DEVMODE.
Thanks for your help.
There are two ways to run a remote server. First is using using DevMode with -noserver and pointing the war directory to the output war directory of the external server. The second way is to use the CodeServer entrypoint and run a WTP server runtime and set the launcher directory to tomcat output war directory.
I prefer the second routine, and built automation into the GPE fork.
http://gwt-plugins.github.io/documentation/gwt-eclipse-plugin/servers/Tomcat.html - see it in action here. There are videos and such.

Spring Boot with Cucumber E2E (Selenium) testing

In my project, I have to current Maven modules setup:
- Application
|- (application code, using Spring Boot 1.2.6)
- E2E-testing (has a dependency to Application)
|- src
|- main
|- java
|- AbstractCucumberTest.java
Before, this used to be a Spring 3 application serving JSP pages, so no Boot included. I refactored it to be a Boot application.
The E2E testing setup basically built a WAR file of the application code, and the E2E module booted a Jetty server, running that WAR. All was well.
Now, after the refactor, not so much.
The Jetty setup no longer works as-is. When I boot the WAR, I'm getting class loading exceptions, which are related to Jetty itself. Now, I'm not hung up on Jetty, it's just a testing container for me. So I started digging around in the Boot documentation, because I was convinced there had to be a way to make it all "Boot'-iful, meaning: I could simply boot the application when launching the tests. And there is, of course, so I ended up with these annotations on my AbstractCucumberTest:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ApplicationConfig.class, loader = SpringApplicationContextLoader.class)
#WebIntegrationTest({"spring.profiles.active=local"})
public abstract class AbstractCucumberTest extends SeleniumTest {
So, basically, I'm loading the application config of the application, and launching the Tomcat server from the test. And all rejoiced, because now the application was successfully booting upon launching a Cucumber test. The application boots, it reads the classpath, Liquibase boots, everything is working alright. I can call the Actuator endpoints, which all work fine. Even the REST endpoints of the application are all working, so Spring MVC is doing its thing.
However, 1 thing is not, and that's serving JSP's -- and that's of course a deal breaker for E2E tests. Every time I surf to a page, I get the same unnerving 404 error. Before you ask: yes, tomcat-embed-jasper and jstl are present. They are present in the application, I even added them to the E2E pom, no luck. In fact, these are the things I tried, but they all failed:
Excluding the tomcat-embed-jasper and jstl dependency from the application
Copying over the JSP's from the application to the resources of the E2E module
Setting up my own CucumberConfig, which basically contained the same configuration as the ApplicationConfig
It just seems to me that the application cannot find the JSP's. Everything else is working just fine, just the JSP's are not found/served.
Does anyone have any thoughts?
Oh, on a side note, I tried using the spring-boot-maven-plugin, to try and boot the application that way. Problem is, though, that it cannot be forked. In the 1.2.6 release, the fork simply ... does not fork. When I say fork, I mean it in the Jetty way: it boots the application, and gives control back to Maven. It instantiates a "stop" command, which Maven can call after all tests have run.
In the 1.3.0.BUILD-SNAPSHOT version, it should be present (using the start goal), but that's still not working for me.
[EDIT] For what it's worth, the Application module is configured to build a WAR file. So it's not JAR packaging.
To whom it may concern, eventually I turned to the Maven Cargo plugin, which works just fine. I configured it in the pom of the E2E testing module. As you can see, my application is marked as a deployable, and the cargo plugin boots at the pre-integration-test phase, and shuts down at post-integration-test phase.
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.16</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<zipUrlInstaller>
<url>
http://archive.apache.org/dist/tomcat/tomcat-8/v8.0.27/bin/apache-tomcat-8.0.27.zip
</url>
</zipUrlInstaller>
</container>
<deployables>
<deployable>
<groupId>my.group.id</groupId>
<artifactId>Application</artifactId>
<type>war</type>
<properties>
<context>/context</context>
</properties>
</deployable>
</deployables>
<configuration>
<type>standalone</type>
<properties>
<cargo.servlet.port>9999</cargo.servlet.port>
<cargo.jvmargs>-Dspring.profiles.active=local</cargo.jvmargs>
</properties>
</configuration>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

Configure Maven to use CXF wsdl2java with Basic Authentication

I have an application that needs to integrate with one of SharePoint's web services. This web service cannot be accessed freely and needs authentication.
As such, the standard wsdl2java Maven plugin in my application gives an HTTP 401 error when the generate-sources phase is executed.
Is there a way to setup Maven/POM so that I can provide a user/password that will generate the stubs?
I have come across some answers saying this is not possible but all answers are older than 1 year. I haven't found if Maven have issued an update on this. One option is to save a local copy of the WSDL (as suggested here) but I would like to avoid having local copies.
Because you mentioned CXF then I suppose you meant cxf-codegen-plugin. It's a bit of a hack but it works.
HTTP authentication credentials can be provided using java.net.Authenticator. One need to just define his own Authenticator class which overrides getPasswordAuthentication(..) method. Then it has to be set as default Authenticator. As far as I know it can't be done declaratively (for instance using environment properties) only programatically using Authenticator.setDefault(..).
In order to call Authenticator.setDefault(..) I would use CXF extension mechanism. Create separate maven project with similar class:
public class AuthenticatorReplacer {
public AuthenticatorReplacer(Bus bus) {
java.net.Authenticator.setDefault(new java.net.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("test", "test123"
.toCharArray());
}
});
}
}
and file src\main\resources\META-INF\cxf\bus-extensions.txt with contents:
org.example.AuthenticatorReplacer::false
Then add newly created project as a dependency to cxf-codegen-plugin:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${project.version}</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>cxf-authenticator-replacer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
</plugin>
This way AuthenticatorReplacer is initialized by CXF extension mechanism and replaces default Authenticator with ours.
An clean alternative to #Dawid Pytel's solution would be to run this class during lifecycle of wsdl class auto generation:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>path.to.AuthenticatorReplacer</mainClass>
</configuration>
</plugin>
Important: your AuthenticatorReplacer has to be a main(String[] args) class and running the code inside.
I verified that Dawid's solution works. Alternatively, you can use SoapUI to pull down and cache the wsdl and then use SoapUi code generation support to use cxf to generate the code.
http://java.dzone.com/tips/generating-client-java-code
Dawid's solution works for me too. It is a little tricky though. In Eclipse, the pom.xml keeps complaining that "wsdl2java failed: Could not load extension class AuthenticatorReplacer". You have to ignore this error message and use the command line:
mvn generate-sources
The Java classes will then be generated successfully.

Resources