Spring auto load changes in jsp without compiling again - java

I come today with a simple question. Is there any plugin I can use in spring so everytime I make changes in one of my .jsp files, it makes a fast re-compiling instead of having to stop the project and compile it all over again?
For references I'm working on Spring Tool Suite and my project uses Maven, I've read about Spring Loaded and used the following code to implement it, but I just can't make it work.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.6.RELEASE</version>
</dependency>
</dependencies>
</plugin>
Can anyone give me any advice about it, or if there's really a way to do this?

Related

How can I create a Spring 5 component index?

Spring Framework 5 apparently contains support for a "component index" which lives in META-INF/spring.components and can be used to avoid the need for class-path scanning, and thus, I assume, improve a webapps' startup time.
See:
The "what's new in spring 5" mention
The jira issue under which the support was developed
Some examples of what the spring.components format seems to be from the change implementing it
How can I create such a component index for an existing web app I plan to upgrade to Spring 5?
(Ideally it would get generated automatically at build time with Maven I imagine, but any other workable approaches would at least give me a starting point to work from)
Spring 5 Has added a new feature to improve startup performance of large applications.
it creates a list of component candidates at compilation time.
In this mode, all modules of the application must use this mechanism as, when the ApplicationContext detects such index, it will automatically use it rather than scanning the classpath.
To generate the index, we just need to add below dependency to each module
Maven:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.0.3.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
Gradle
dependencies {
compileOnly("org.springframework:spring-context-indexer:5.0.3.RELEASE")
}
This process will generate a META-INF/spring.components file that is going to be included in the jar.
Reference : 1.10.9. Generating an index of candidate components
The META-INF/spring.components files are generated by an annotation processor library called spring-context-indexer. If you add this library as "annotation processor path" to the maven-compiler-plugin, the files will be generated automatically at build time:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.0.6.RELEASE</version>
</path>
</annotationProcessorPaths>
...
</configuration>
</plugin>
This setup requires maven-compiler-plugin version 3.5 or greater.
See also: https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#annotationProcessorPaths
Kotlin + Maven:
To generate the Spring Component Index when building with Maven and Kotlin:
Kotlin Maven Plugin includes Kapt - Kotlin Annotation Processing Tool. It has a goal kapt which needs to execute before compile (it uses the sources, not the bytecode.
See also:
https://kotlinlang.org/docs/kapt.html#using-in-maven
https://maven.apache.org/ref/3.8.6/maven-core/lifecycles.html
I put the execution into a profile, so that I can get rid of this if not needed.
mvn install -PcreateSpringComponentIndex
Important: You need to keep this updated for each compilation as a matter of habit, otherwise Spring won't pick the new(ly) annotated classes as components! That also means, that if skipping the generation, you need to mvn clean.
Important: When using "shading" (putting all classes and resources into a single flat jar), the files META-INF/spring.components need to be merged! Otherwise one of them will be picked randomly and Spring won't detect any other components. (It's better to avoid shading and pack the dependencies as JARs within a JAR).
Example:
<!-- May speed up the app boot by a couple of seconds. See https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-scanning-index -->
<profile>
<id>createSpringComponentIndex</id>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-maven-plugin</artifactId><version>${kotlin.version}</version>
<executions><execution><id>kapt</id><goals><goal>kapt</goal></goals><phase>process-classes</phase></execution></executions>
<configuration>
<sourceDirs><sourceDir>src/main/kotlin</sourceDir><sourceDir>src/main/java</sourceDir></sourceDirs>
<annotationProcessorPaths>
<annotationProcessorPath><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><version>5.3.23</version></annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><version>5.3.23</version><scope>provided</scope></dependency>
</dependencies>
</profile>

Using Eventuate framework

I have juste starting using evetn
I'm playing with some event sourcing things. This is the first time that I use that concept. After googling I found eventuate which is a java framework that helps you to implement that concept. I get started with that example:
https://github.com/eventuate-examples/eventuate-examples-java-spring-todo-list
I tested it and it looks very good. In that project there is many spring-boot project. Every microservice is a spring-boot project.
My question is How I can do in my IDE, eclipse, if I want to develop some services?
Best regards
Spring Boot projects are Maven build , so even you can add Maven dependencies and plugins/properties in the project for eventuate. Eventuate is a framework that has integration with Gradle and Maven project ( Visit http://eventuate.io/docs/javav2/maven-gradle-config.html ). For your refrence , I am adding some dependencies that might be help to you :
<dependencies>
<dependency>
<groupId>io.eventuate.client.java</groupId>
<artifactId>eventuate-client-java-spring</artifactId>
<version>${eventuateClientVersion}</version>
</dependency>
<dependency>
<groupId>io.eventuate.client.java</groupId>
<artifactId>eventuate-client-java-test-util</artifactId>
<version>${eventuateClientVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.eventuate.local.java</groupId>
<artifactId>eventuate-local-java-jdbc</artifactId>
<version>${eventuateLocalVersion}</version>
</dependency>
<dependency>
<groupId>io.eventuate.local.java</groupId>
<artifactId>eventuate-local-java-embedded-cdc-autoconfigure</artifactId>
<version>${eventuateLocalVersion}</version>
</dependency>
</dependencies>
Make sure to add this client library :
<properties>
<eventuateClientVersion>0.11.0.RELEASE</eventuateClientVersion>
<eventuateLocalVersion>0.5.0.RELEASE</eventuateLocalVersion>
</properties>

Packaging war with new gwt maven plugin (having migrated from default maven plugin)

I've stated using Thomas Broyer's gwt maven plugin as it allows me to run gwt 2.8-rc2. I've got it running with the codeserver fine and with minimum effort.
However now I'm trying to figure out how to use it to do a full compile and package.
Simply running maven install (I expected this to work as it does work with the default) does not actually run the gwt compile.
Then it talks about various packaging formats etc and I'm not sure why these are necessary?
I assume someone has got this plugin packaging the war and has also migrated from the original plugin...
This is my plugin config - I am using skipModule as I've already got a module configured the way the other plugin expects.
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.0-rc-6</version>
<extensions>true</extensions>
<configuration>
<moduleName>com.afrozaar.ashes.web.AshesWeb-safari</moduleName>
<skipModule>true</skipModule>
<style>DETAILED</style>
<!-- <logLevel>DEBUG</logLevel> -->
<classpathScope>compile+runtime</classpathScope>
</configuration>
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.8.0-rc2</version>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>2.8.0-rc2</version>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>2.8.0-rc2</version>
</dependency>
</dependencies>
</plugin>
You're missing "executions" in your plugin configuration to run the compile goal (works the same as with the CodeHaus plugin).
My plugin works better when you separate client and server code into distinct Maven modules, which is why this setup is not clearly documented (because I actively discourage it). You can have a look at the samples in the GWT git repository to find examples similar to your case though.
BTW, I believe you can use rc2 with the CodeHaus plugin rc1; that's probably why you added those dependencies, which are useless with my plugin.
See also https://tbroyer.github.io/gwt-maven-plugin/migrating.html

Can we implement a Java library by using Spring Boot?

As guided by the thread's name, I would like to create a JAVA library by using Spring Boot. I have found this thread: Creating a library jar using Spring boot. However, that thread's objectives seem to be solved by implementing it as a REST API.
Currently, I am developing a Spring-based JAVA library by using Spring Boot. And, I have tried to package as a jar file and let another JAVA application to use it in term of a JAVA library. Unfortunately, I found that when the caller application invokes some methods of the added library, configurations which are defined inside the library do not work at all.
It also shows an error like "CommandLineRunner does not exist".
For more information, a snippet of the pom.xml file is shown below. According to the configuration, I do not include dependencies for web applications.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
When designed in the correct way this should not be a problem at all. But in detail it depends which features you're using. Since Spring supports external library like JPA, Websocket,..
There are two important annotations to develop a library and use it in another project.
The first one is simply #Configuration and the other one is #Import.
Library Project
Put a class in the root package which looks something like this.
#Configuration // allows to import this class
#ComponentScan // Scan for beans and other configuration classes
public class SomeLibrary {
// no main needed here
}
Other Project using the library
As usually put a class in the root package of your project.
#SpringBootApplication
#Import(SomeLibrary.class) // import the library
public class OtherApplication {
// just put your standard main in this class
}
It is important to keep in mind, that other things might be necessary depending on what your using in terms of other frameworks.
For example if your using spring-data the #EntityScan annotation extends the hibernate scan.

Run Spring-boot's main using IDE

I have a spring-boot application that needs to:
Be deployable as a war in a servlet container
Be runnable via `mvn spring-boot:run``
I'd also like to be able to run this application in my IDE (Eclipse or IntelliJ IDEA Community) by right clicking on the main and running it.
Here are the interesting parts of my pom.xml (Note that I do not inherit from spring-boot-starter-parent pom):
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here's my SpringBootServletInitializer:
#Configuration
#EnableAutoConfiguration
#ComponentScan("com.company.theproject")
public class Application extends SpringBootServletInitializer
{
private static final Logger logger = LoggerFactory.getLogger(Application.class);
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(Application.class);
}
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
When running the main inside an IDE I get the following error:
org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
... 12 common frames omitted
Seems like mvn spring-boot:run does some more magic that does not happen when running the main directly.
Removing the provided scope from the spring-boot-starter-tomcat dependency fixes this issue but causes trouble when the war is run inside a servlet container.
Right now the only "fix" I've found is to run mvn spring-boot:run within IntelliJ IDEA instead of running the main directly. While this is an acceptable workaround, I'd still like to know why this doesn't work and if it can be fixed.
A workaround that is strongly inspired from https://youtrack.jetbrains.com/issue/IDEA-140041 is to start your main class with the test classpath (which includes the embedded servlet.)
Steps (IntelliJ 16):
Run -> Edit Configurations -> Add new configuration -> Pick Application type.
Set Main class to <your.main.class>
Set Use classpath of module to <*>_test (the test module!)
Ok and Run it!
I believe this could be related to https://youtrack.jetbrains.com/issue/IDEA-107048
IntelliJ IDEA is not injecting the provided dependencies into the CLASSPATH and as Andy stated this is why spring is unable to create the embedded servlet container.
They have a feature request since 2005 about this: https://youtrack.jetbrains.com/issue/IDEABKL-99
Workarounds mentioned in the comments includes having a fake module with the necessary libs and using it as classpath, using the -Xbootclasspath JVM argument or using custom maven profiles for running (compiled) vs building (provided).
I had the same problem using IntelliJ 2018.
Initially, Make sure that you have added the maven library for the spring project in your IntelliJ.
My solution is:
Go to Run -> Edit Configurations.
Select Application && choose your current project.
Check Include dependencies with "Provided" scope.
OK -> RUN
I was able to make this work by changing the scope of the spring-boot-starter-tomcat dependency to "compile" under Project structure->Dependencies tab. This doesn't effect pom.xml but allows this dependencies to be available to spring boot run configuration
Click here for image on where to change this setting in idea
mvn spring-boot:run includes provided dependencies when it's creating the classpath. It sounds like IntelliJ IDEA does not. Without Tomcat on the classpath, Spring Boot's unable to create an embedded servlet container which causes the exception you're seeing. Arguably this is a bug in IntelliJ as, if there's no container to provide the dependency, then it really needs to be on the classpath.
You may be able to fix the problem by overriding the default classpath that IntelliJ uses when running the main method to include the spring-boot-starter-tomcat dependency.
I find this page, and use the maven profile to manage the profiles.
<profiles>
<profile>
<id>PROD</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>DEV</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>TEST</scope>
</dependency>
</dependencies>
</profile>
</profiles>
and config the main class beforeLanuce,set the command
mvn clean compile -Pdev
I was able to work around this problem in Intellij IDEA 2017.2 by adding the provided libaray (spring-boot-starter-tomcat) to the project configuration.
Select File -> Project Structure. Select Libraries and add a new project library (type = From Maven...). Search for spring-boot-starter-tomcat using the dialog, select the correct version and add it by clicking on OK. The library is added to the list of external libraries.
The disadvantage is that if the Spring Boot version is changed then you will have to remember to delete this library and add the new version.
Using the profile and instructions below, you can add a profile to maven that allows development in IntelliJ without changing things for other environments.
<!-- Leave original dependency as-is -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<!-- Enable this profile to run in IntelliJ. IntelliJ excludes provided dependencies from compile by default. -->
<profile>
<id>intellij</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Click the Maven Projects button on the right side of IntelliJ, and under Profiles, select intellij.
Follow these steps:
On the top right side of intellij window, click the drop down and select edit configuration and a new window will open.
In this window, on top left side, click "+" button and select sprint boot.
Then add you main class, and other details as shown in screenshot.
Now Run the application.

Categories

Resources