Change port of deployed Spring project on Wildfly - spring

Note to moderator: Other existing questions in SO make reference to the default interface. I'm not interested on changing that. I need to specifically change the port of each deployment.
Other questions regard wildfly running in standalone mode. I'm running it as a Windows Server Service.
Based on this please do not close the question.
Now, the question:
Taking as a reference the following Spring application, running on Wildfly on Windows Server 2019 installed as a service:
#Configuration
#SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
static Logger logger = LoggerFactory.getLogger(DemoApplication.class);
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<DemoApplication> applicationClass = DemoApplication.class;
}
When I was using Tomcat, changing the web service port was easy as adding:
Application.properties
server.port=8093
Resulting in the desired URL:
http://127.0.0.1:8093/swagger-ui.html
However, deploying on Wildfly proved to be harder. At first, it was the .war name and the wrong context root, which I fixed by adding the following changes:
pom.xml
<finalName>${project.artifactId}</finalName>
src\main\webapp\WEB-INF\jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.jboss.com/xml/ns/javaee
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<context-root>/</context-root>
</jboss-web>
However, there's the last problem. The web service is being exposed on http://127.0.0.1:8080/swagger-ui.html instead of using port 8093.
How can I change the port of each deployed web service in Wildfly, instead of the default 8080?

The server.port property only controls the listening port of an embedded server in a Spring boot app (tomcat, jetty, etc.).
The app's port in a standalone application server is specified during the deployment. The easiest way to do this on Wildfly is via the wildfly-maven-plugin (https://docs.jboss.org/wildfly/plugins/maven/latest/deploy-mojo.html):
<build>
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>2.1.0.Final</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<configuration>
<filename>${project.build.finalName}.war</filename>
<hostname>127.0.0.1</hostname>
<port>8093</port> <!-- <<<<<<<< -->
<username>my-wildfly-user</username>
<password>my-wildfly-password</password>
</configuration>
</plugin>
<!-- ... -->
</plugins>
</build>

Related

Springboot JPA with Tomcat 7

I have been trying to deploy springboot with JPA on Tomcat 7. The app works fine when running with java -jar. But with deployed on Tomcat, it is often saying can't find the bean with extended JpaRepository interface.
What is the proper way to deploy springboot on Tomcat 7?
Thanks in advance.
some times this will helps
in Application.java
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class Application extends SpringBootServletInitializer
Add this Dependency and Plugin to pom.xml
<!--For Build War File-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
This works for me
Hope this will helps...!

Spring boot maven executable jar not running with Double click

Created a maven jar of a simple spring boot application.
If I try and execute the jar file from the command line using java -jar x.jar and it runs ok, even see all the traces of spring boot..booting up..
If try to execute it just by double clicking it with the mouse, it wont run. A command window pops up for a milli second and vanishes and if I try to get to an exposed endpoint (HTTP Rest - Get)..site cant be reached error..
The project is a sample Eureka server, so contains cloud dependencies..
Any ideas what could be the problem, is it just some environment setting?!
Regards,
From the POM:
<groupId>example.demo</groupId>
<artifactId>EurekaServiceDiscovery</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
.
.
.
.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
.
.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Basic Spring Eureka example, virtually no code except:
#EnableEurekaServer
#SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
Did you follow this?
https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
To create a ‘fully executable’ jar with Maven, use the following plugin configuration:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
The following example shows the equivalent Gradle configuration:
bootJar {
launchScript()
}
You can then run your application by typing ./my-application.jar (where my-application is the name of your artifact). The directory containing the jar is used as your application’s working directory.
There is no problem at all
Doubble click on jar fie and executing by command are not same
java -jar x.jar
Either execute from eclipse or from command prompt.
Else change Windows(operating system) setting or change execution setting in maven config to execute from command prompt

How to deploy swagger generated spring code (Tomcat)

I used the example given by SwaggerCodeGen to create a Server via SpringBoot.
I build the project with maven and run it local. Everythings works fine.
Now I want to deploy this project on a tomcat (version 7).
So I changed the packing from jar to war
<packaging>war</packaging>
and moved the *.war file to tomcat\webapps folder
I tried to run
localhost:8080/app
which return an 404
same with
localhost:8080/app/swagger-ui.html
localhost:8080/v1/app/
localhost:8080/v1/app/api-docs
Unfortunatly, I have got no experience with tomcat.
The Project doesn't contain a web.xml. Is it necessary?
Do I need to create a Servlet?
Any help would be appreciated.
In your POM you need:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
and
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.9</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
Your SpringBoot Application should also look like this:
public class SpringBootServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringBootServiceApplication .class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringBootServiceApplication .class);
}
}

Cannot start an OSGI bundle that embed spring boot in liferay 7

I want to develop a standalone bundle that implement a service using spring boot and spring data jpa (without web).
The bundle aims to create a spring context to facilitate the creation of Repository, and in teh bundle activator, I create the spring boot application, get an implementation of service that use the injected repository and this service will be registered as an OSGI service.
The bundle will be deployed on Liferay 7 so there is no ready bundles to help exporting packages (for jpa ...), to make simpler the idea is to have a standalone bundle that embed all dependencies in the bundle classpath (no package to import from outside the bundle)
Is there any sample that can help ? and is that a good idea ?
The problem was, when trying to start the bundle, it fails with "Caused by: java.lang.ClassNotFoundException: org.osgi.framework.BundleActivator .."
The following classes are simplified sampel to demonstates the problem (normally it must be a separate bundle that define and export the api that will be implemented by the bundle in question, but in this sample this is a unique bundle with 4 classes)
1/ The bundle activator class
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.springframework.context.ApplicationContext;
public class Activator implements BundleActivator
{
#Override
public void start(BundleContext context) throws Exception
{
ApplicationContext springCtx = SpringFramework.getContext();
UserDao dao = springCtx.getBean(UserDao.class);
userDaoReg = bc.registerService(UserDao.class.getName(), dao, new Hashtable());
}
#Override
public void stop(BundleContext context) throws Exception
{
/** **/
}
}
2/ class to launch the spring boot application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
#SpringBootApplication
public class SpringFramework {
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
context = SpringApplication.run(SpringFramework.class);
}
public static ConfigurableApplicationContext getContext()
{
if (context == null) {
context = SpringApplication.run(SpringFramework.class);
}
return context;
}
}
3/ The UserDao to be registered as a service
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDao extends JpaRepository<User, Integer>
{
}
4/ and a simple JPA Entity class "User"
And these are dependencies and plugin used in the pom.xml
<dependencies>
<!--OSGI dependencies-->
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<scope>provided</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.RELEASE</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>!*</Import-Package>
<Bundle-Activator>hello.Activator</Bundle-Activator>
<Embed-Dependency>*</Embed-Dependency>
<!--<Embed-Transitive>true</Embed-Transitive>-->
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This is the generated manifest in the jar
Manifest-Version: 1.0
Bundle-SymbolicName: test-spring-boot-no-web
Archiver-Version: Plexus Archiver
Built-By: XXX
Bnd-LastModified: 1475774161783
Bundle-ManifestVersion: 2
Embed-Dependency: *
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Spring-Boot-Version: 1.3.0.RELEASE
Tool: Bnd-3.2.0.201605172007
Main-Class: org.springframework.boot.loader.JarLauncher
Embedded-Artifacts: org.osgi.core-6.0.0.jar;g="org.osgi";a="org.osgi.c
ore";v="6.0.0",slf4j-api-1.7.13.jar;g="org.slf4j";a="slf4j-api";v="1.
7.13",spring-boot-starter-1.3.0.RELEASE.jar;g="org.springframework.bo
ot";a="spring-boot-starter";v="1.3.0.RELEASE",spring-boot-starter-dat
a-jpa-1.3.0.RELEASE.jar;g="org.springframework.boot";a="spring-boot-s
tarter-data-jpa";v="1.3.0.RELEASE",persistence-api-1.0.2.jar;g="javax
.persistence";a="persistence-api";v="1.0.2",javax.transaction-api-1.2
.jar;g="javax.transaction";a="javax.transaction-api";v="1.2"
Export-Package: hello;version="1.0.0"
Bundle-Name: spring-boot-no-web
Bundle-Version: 1.0.0.SNAPSHOT
Bundle-ClassPath: .,org.osgi.core-6.0.0.jar,slf4j-api-1.7.13.jar,sprin
g-boot-starter-1.3.0.RELEASE.jar,spring-boot-starter-data-jpa-1.3.0.R
ELEASE.jar,persistence-api-1.0.2.jar,javax.transaction-api-1.2.jar
Bundle-Activator: hello.Activator
Start-Class: hello.SpringFramework
Created-By: Apache Maven Bundle Plugin
Build-Jdk: 1.8.0_101
I saw 2 questions in your post so I'll try to answer those:
Is there any sample that can help ?
I don't think so! What you are trying to do seems weird to me. See below for details.
... is that a good idea ?
You are saying you want "standalone bundle" that "will be deployed on Liferay 7"! It may be you just picked the wrong words but the way you state it, you are trying to have mutually exclusive things.
There is no such thing as "standalone bundle". I assume you mean standalone java application (executable Jar file that has the OSGi framework embedded). You can build such applications in a number of different ways. For example there is excellent tutorial how to do this from EnRoute. You can not however deploy such executable jar as it typically is not a OSGi bundle. While technically you can make it a bundle, you may run into all kinds of issues due to the embeded runtime and dependencies.
In Liferay 7 (and any outher product that has OSGi container) you can run a bundle in the runtime environment the product defines. The bundle must be resolvable at runtime. It may have all it's dependencies embedded but that defeats the purpose of modularity unless it provides something to outher bundles (which does not seem to be your case).
From that perspective what you are trying to do seems to be a bad idea. Moreover Spring Boot is a framework to build stand alone java applications and as such have it's own assumptions. Making it work inside an OSGi container is likely not a trivial task (if at all possible)
Perhaps better idea would be to have some bundles providing the business logic only. Then you could deploy those bundles in Liferay and laverage Liferay's capabilities to serve REST servces. You could use the exact same bundles to cunstruct standalone application that uses Spring or CXF or something else.
Notes about your code
your main class is org.springframework.boot.loader.JarLauncher. If you run this jar it will start Spring which likely will be totally unaware of OSGI runtime.
you have org.osgi.core-6.0.0.jar is your bundle's classpath with is basically the OSGi's runtime. This will cause issues if deployed into a OSGi runtime and my be the reason why you see
Caused by: java.lang.ClassNotFoundException: org.osgi.framework.BundleActivator ..

Spring Boot profiles not active when set with maven plugin

I'm trying to set spring profiles when starting Tomcat for integration tests in maven like this:
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<profiles>
<profile>testProfile</profile>
</profiles>
</configuration>
...
The profile is definitely not active.
On the other hand the following does work and the requested profile is active:
<jvmArguments>-Dspring.profiles.active=testProfile</jvmArguments>
The problem here is that we can't stop the server, which is a problem when running automated integration tests.
I'm using spring boot "1.4.0.RELEASE".
My questions:
1. Why does the profile tag not work? (Bug?)
2. Why id the JMX bean not found when trying to shutdown the server in the "stop" goal? Does this something have to do with the forking because of the jvmArguments?
I was ignoring the args in the main method. Passing them to the Spring application solved it:
public static void main(String[] args) throws Exception {
SpringApplication.run(RunServer.class, args);
}

Resources