How to deploy a Spring boot vaadin project on jetty using intellij, the Idea behind that is to refresh the project after each changes without restarting the server.
I don't really understand the people who downvote a question without answering it. however here is the answer:
in Spring framework using spring-dev-tools, you have the option to deploy the project whenever the class path changes( in intellij the class path change event is triggered when we rebuild the project, in eclipse class path change event is triggered as soon as we hit the save file of any class). Server will restart (tomcat or jetty) and load the project (Restart method).
we could overcome this expensive approach using third party plug-ins such as JRebel. JRebel will only deploy the class that has been changed.
consider developing a web app and consider making about 100 runs a day, everytime the server restarts it consumes 3 seconds. do the math
Related
I am new to Spring Boot from php world. In Php development, it is simple to make changes on the file, upload and run.
But on Spring boot, my development relies on remote ubuntu server, every time I make change in *.java, I have to build the Fat Jar, upload the Jar, kill the current java process on ubuntu, and run the java -jar my.jar again, which spend much time on the upload because the Jar is about 60 mb.
Is there any way I can work like php, just upload the changed file, so the spring boot just compile the class and run?
Does change to build *.war help to faster deployment?
There are a few option to mitigate the roundtrip of building the jar file and upload it.
Hot-swap: For minor changes, you can hot-swap changes automatially when you have a remote-debugger attached. I use Intellij as Ide, which provide this out of the box after a file is recompiled, see more at this link how to enable it.
Reloading tool: use a tool that are designed to reload Java classes, such as JRebel which extends the classloader and updates a class if a change has been detected. However, they are often only available in a paid version.
Spring Boot dev-tools: this tool also monitors changes and restart the application with the new changes (so no need to rebuild the jar file). It is possible to use on a remote application. See this link for more info.
Using a war file is different concept since a war file is executed inside an application container (e.g a Wildfly server). You can dynamically upload a war file to a running application server, which will only restart the war file. But I'm not sure if this will lead to faster deployment, however it is a different approach how the application is run.
One of the main benefits of grails, which is based on Spring, is that you dont need to rebuild and re-run the entire application (which takes minutes) each time you change a line of code, it just recopiles that one file and auto-loads the changes.
Following this tutorial:
https://spring.io/guides/gs/spring-boot/
To run the app, you have to use the command line and do this outside of intellij:
./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar
If you change a line of code, e.g. in a controller, you have to kill the application, rebuild it and restart it, which takes a while.
I came across something called automatic restart in dev tools. Is this something to do with auto-reloading of changes, and if so, how is it used?
If a class is changed , I am sorry that Spring boot devtools will not just reload that changed classes but it will restart the whole application automatically . But this restart should be faster than the normal cold start based on what the docs said :
The restart technology provided by Spring Boot works by using two
classloaders. Classes that do not change (for example, those from
third-party jars) are loaded into a base classloader. Classes that you
are actively developing are loaded into a restart classloader. When
the application is restarted, the restart classloader is thrown away
and a new one is created. This approach means that application
restarts are typically much faster than “cold starts”, since the base
classloader is already available and populated.
If you need to just reload the changed classes , you may consider to use JRebel which is not free.
To use spring boot devtools , just includes its dependency and then start the application as usual using IDE.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
It will the monitor the classpath folders and then restart the application if there are any changes in these folders.
In case of Eclipse , what you need is to ensure Project ➡️ Build Automatically is selected. Once the source codes are changed , Eclipse will then just compiled that changed sources codes to the classes in the classpath folders automatically which trigger devtools to restart the application.
Based on the #Ken Chan answer but very briefly
For Eclipse - click in the menu "Project" -> select "Build Automatically"
In my case I was running some spring boot server - I had to stop the server, enable "Build Automatically" like on the picture, then start the server again and on every change - the code recompiled.
Our application are built on Spring boot, the app will be packaged to a war file and ran with java -jar xx.war -Dspring.profile=xxx. Generally the latest war package will served by a static web server like nginx.
Now we want to know if we can add auto-update for the application.
I have googled, and people suggested to use the Application server which support hot deployment, however we use spring boot as shown above.
I have thought to start a new thread once my application started, then check update and download the latest package. But I have to terminate the current application to start the new one since they use the same port, and if close the current app, the update thread will be terminated too.
So how to you handle this problem?
In my opinion that should be managed by some higher order dev-ops level orchestration system not by either the app nor its container. The decision to replace an app should not be at the dev-ops level and not the app level
One major advantage of spring-boot is the inversion of the traditional application-web-container to web-app model. As such the web container is usually (and best practice with Spring boot) built within the app itself. Hence it is fully self contained and crucially immutable. It therefore should not be the role of the app-web-container/web-app to replace either part-of or all-of itself.
Of course you can do whatever you like but you might find that the solution is not easy because it is not convention to do it in this way.
I am having three modules in my Maven project:
parent
rest-api # Spring REST API
web-client # AngularJS web client
application # Project to bundle it all up for a standalone
I am not sure if I have here an "elegant" solution so please hit me with a stick if that is complete garbage, but this is how it works - or how it's supposed to work:
rest-api
Module rest-api does simply offer the REST API and other core functionality - basically it is pure server code. It is a jar artifact.
web-client
To separate client and server code I am having the module web-client. It is a war project that hold the client webapp.
application
This module is supposed to glue it all up. It depends on rest-api and web-client. It does two important things:
It's pom.xml uses the spring-boot-maven-plugin to build a standalone runnable jar - my ultimate goal
It provides the main(String args[]) method that starts the #SpringBootApplication with SpringApplication.run(EasyModelAccessServer.class, args);
What I am currently able to is tell Eclipse to run this in a servlet container. The server boots up and I my two resources, the rest-api and the web-client working. Everything is fine so far.
The issue
What is not fully working is the standalone. If I package up the whole thing and run the server:
$ path/to/application: mvn clean package
$ path/to/application: java -jar target/application.jar
Only the REST API will work. The reason is because the web-client is not added or introduced as a web app to the Spring built-in Tomcat.
The question
is how I can make this work. There are two options which come to my mind:
Somehow sneak in the web-client.war file into the application.jar such that it is available as a resource and programmatically call tomcat.addWebapp("/web-client", "path/to/web-client.war") (or something like that) to load the additional service
Hope that the spring-boot-maven-plugin or another Spring Maven plug-in can do that for me and find somebody that links me to an example.
I've tried it with 1. but I didn't succeed to move web-client.war into application.jar but I am also not sure if I should actually do that.
FAQ
Q: "Why do you separate everything instead of merge all those modules into a server module where the Spring Maven plug-in would do everything for you out of the box?"
A: I really want to separate the client code from the server code. I could however merge web-client into application but last time I tried that I had 10 other issues why this did not work out so I decided to keep it that way and that it actually shouldn't be so hard to load an additional server resource.
Q: "Can I take a look at the project?"
A: Yes, you can. Just take a look: https://github.com/silentsnooc/easy-model-access Please forgive me that I am currently using tabs instead of whitespaces - I am going to change that as soon as I got everything up and running.
I am trying to build an project in Eclipse (actually I'm using RAD, so basically eclipse, and when I say 'Java EE Project' I mean an 'Enterprise Application Project').
My Enterprise Application Project (the 'EAR' project) has two module projects :
- service
- web
The service project has some stuff in it, all wired up using Spring.
The web project has its own stuff in it, all wired up using Spring. The UI stuff in the web project needs to use the stuff in the service project.
Both projects are included in the EAR project as modules.
The web project lists the 'service' project as a dependent project in the build path, it's checked off for export, and also has it listed as a EE Module Dependency.
I'm having a really hard time to get this working though:
The spring context in the web project is of course what gets loaded when the application is deployed, and it imports the spring config I need from the service project. This seems to be working fine.
When spring tries to instantiate a bean it throws a ClassNotFoundException. On the very first bean.
I tried simply copying the spring config from my service context and pasting it into my web context, but I got the same ClassNotFoundException.
I have tried instantiating an object of that type (the class that spring says cannot be found) in the java controller class in the web project, and it is successful, both at compile time (no compile errors) and at runtime (no exceptions).
So the classes from my service project are not available on the classpath when spring tries to use them.
Any ideas what's going on here and/or what I might be able to do about it?
There is a class loader policy that you should use ParentClass First . That will be managed either through Application.xml or through web.xml . You need to check your xml's then try.
It's a class loader issue.
Since you're using Spring, I'll assume that you don't have EJBs. If that's the case, why do you need an EAR? Deploy the whole thing as a web project, in a single WAR.
Put all your .class and Spring configuration .xml files in WEB-INF/classes. Load the configuration using org.springframework.web.context.ContextLoaderListener.
I seem to have fixed this - I'm not sure exactly what the problem was but there must have been a small typo in my spring config. I decided to just start fresh with a new spring config and when I started building the new one back up things were working fine. There must have been a problem with the old one.
Thanks for the suggestions though.
Unfortunately we're not always able to change project structure. We're working on structures other people have put in place.
I looked into the ParentClassFirst vs ParentClassLast setting - it seems on websphere the ParentClassFirst setting is the default if you don't specify anything, so I'm leaving it without specification to get that functionality.
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/crun_classload.html