Why does the addition of a dependency in Maven trigger functionality? - java

I have a simple question: I'm just getting started with Open API 3. For this purpose I have added the following dependency in Maven.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.2.30</version>
</dependency>
With the addition of this dependency, can I access the service via localhost:8082/v3/api-docs without having previously set anything and called a function of the dependency? How can this happen? What is the concept behind this ?

Adding the OpenAPI dependency in your Maven pom.xml just adds the librar(ies) to your project. That's all.
If this were a "traditional" project (like a JSP web app, for example), you'd have to write the code to create the web service (e.g. "localhost:8082/v3/api-docs").
But it sounds like your project might be Spring Boot:
https://developer.ibm.com/technologies/java/tutorials/j-spring-boot-basics-perry/
If you let it, Spring Boot will use its #EnableAutoConfiguration
annotation to automatically configure your application.
Auto-configuration is based on the JARS in your classpath and how
you’ve defined your beans:
Spring Boot uses the JARs you have specified to be present in the CLASSPATH to form an opinion about how to configure certain automatic
behavior. For example, if you have the H2 database JAR in your
classpath and have configured no other DataSource beans, then your
application will be automatically configured with an in-memory
database.
Spring Boot uses the way you define beans to determine how to automatically configure itself. For example, if you annotate your JPA
beans with #Entity, then Spring Boot will automatically configure JPA
such that you do not need a persistence.xml file.

It is called convention over configuration.
Wiki link https://en.wikipedia.org/wiki/Convention_over_configuration

Related

Integrating Camunda webapps in spring framework

I setup Camunda in my Spring 3 project (Tomcat server) using this guide. I embedded the workflow engine in my project.
However, I cannot access the cockpit when I go to the url http://localhost:8080/camunda/app/. I get a 404 error.
I see that there is a dependency to be added in case of Spring boot according to this guide
But I see no such dependencies available for Spring. Do we not get access to webapps while integrating Camunda with Spring?
Also asked this question in the camunda form: https://forum.camunda.org/t/integrating-camunda-webapps-in-spring-framework/27661
You'll need the following dependency.
<dependency>
<groupId>org.camunda.bpm.webapp</groupId>
<artifactId>camunda-webapp-webjar</artifactId>
</dependency>
Then ensure you have the required configurations. Refer the spring boot auto configuration set up here and the web app initialiser here.

spring boot wants me to start server because I have servlet on classpath

today I faced following problem:
One of my core dependencies unfortunately pulls servlet.api to my classpath. Because of this, my spring-boot thinks I'm automatically a server, while I'm a desktop app, and does not want to start without some factories needed to web.
This is what it says:
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
Unfortunately I can't get rid of this dependency, and for them to fix their transitive dependencies will probably take some time.
Is there any hack to walk around this?
Thanks
If you're using Spring boot 2.x, you can disable the web application by setting the spring.main.web-application-type property to none:
spring.main.web-application-type=none
If you're using Spring boot 1.x, you could set the spring.main.web-environment property:
spring.main.web-environment=false
The reason this changed is because Spring boot 2.x can now be configured to be either reactive, servlet-based or none, while in Spring boot 1.x it was either servlet-based or none (so it could be just a boolean).
Alternatively, you can also use a custom SpringApplication instance as mentioned by the documentation (and in the comments):
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class)
.web(WebApplicationType.NONE) // Use this for Spring boot 2.x
.web(false) // Use this for Spring boot 1.x
.run(args);
}
Not all Spring applications have to be web applications (or web services). If you want to execute some code in a main method but also bootstrap a Spring application to set up the infrastructure to use, you can use the SpringApplication features of Spring Boot. A SpringApplication changes its ApplicationContext class, depending on whether it thinks it needs a web application or not. The first thing you can do to help it is to leave server-related dependencies (e.g. servlet API) off the classpath. If you cannot do that (for example, you run two applications from the same code base) then you can explicitly call setWebApplicationType(WebApplicationType.NONE) on your SpringApplication instance or set the applicationContextClass property (through the Java API or with external properties).
You are missing some required JAR file to run it as web application. Please make sure to that you have included spring-boot-starter-web.jar file.
If we are using maven, do it as follows.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>

Spring boot - new project

I would like to create a java project (none web) to take advantage of the spring features like dependency injection, transactional data, Autowiring etc,
Some of the features I would like to use:
#Service
#Autowired
#Repository
#Transactional
JdbcTemplate
Stuff I don't need:
Hibernate
#Controller
#Path
I am struggling to create that initial Spring project with the initial configuration
I was wondering if I can create that initial Spring project using the new spring boot integration in eclipse?
if its possible what is the correct modules to select from this screen?
The annotations are included in the org.springframework (spring-context) so if you create the default project you will get a pom with the spring-boot-starter dependency which includes the org.springframework.
Regarding to the JDBC it's included in the spring-boot-starter-jdbc.
I think selecting Aspects from Core for all annotations except #Transactional. For #Transactional you should go within SQL and select dependency for any particular db that you are using like PostgreSQL,MySql,SQL Server etc.
Hope this helps !

Use embedded database for test in spring boot

I have a spring boot application, it has a couple of #Entity classes and #RepositoryRestResource repositort interfaces for them. Now I want to write some tests, where I can check that I can add a new record into my database using those repositories, but I don't want to use my configured MySQL database for it, but instead I want to use some embedded db like H2. At the moment I have an application.properties file, which looks like this:
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=qwerty123
Question: How do I configure my app to use other db for tests? I have no xml in my project, everything is based on annotations. I tried to define #Configuration class with #Bean to create DataSource and then use it with #ContextConfiguration annotation on test class, but it says that it can't load context.
If you are using a Maven project, you can add a application.properties file into your src/test/resources, for example with the following content.
# Create DDL
spring.jpa.hibernate.ddl-auto=create
# H2 in local file system allowing other simultaneous connections
spring.datasource.url=jdbc:h2:~/test;AUTO_SERVER=TRUE
Also, you need to include H2 as dependency (pom.xml):
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
Spring Boot provides 2 magic annotations related to JPA autoconfigs for tests: #DataJpaTest and #AutoConfigureTestDatabase.
The javadoc says:
By default, tests annotated with #DataJpaTest will use an embedded
in-memory database (replacing any explicit or usually auto-configured
DataSource). The #AutoConfigureTestDatabase annotation can be used to
override these settings.
If you are looking to load your full application configuration, but
use an embedded database, you should consider #SpringBootTest combined
with #AutoConfigureTestDatabase rather than this annotation.
So, the only thing you absolutely need is a dependency in your pom file:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
That's it. However, spring boot spec also has 2 useful caveats:
You need not provide any connection URLs. You need only include a
build dependency to the embedded database that you want to use.
If you are using this feature in your tests, you may notice that the
same database is reused by your whole test suite regardless of the
number of application contexts that you use. If you want to make sure
that each context has a separate embedded database, you should set
spring.datasource.generate-unique-name to true.
And another one:
If, for whatever reason, you do configure the connection URL for an
embedded database, take care to ensure that the database’s automatic
shutdown is disabled. If you use H2, you should use
DB_CLOSE_ON_EXIT=FALSE to do so. If you use HSQLDB, you should ensure
that shutdown=true is not used. Disabling the database’s automatic
shutdown lets Spring Boot control when the database is closed, thereby
ensuring that it happens once access to the database is no longer
needed.
That's almost all you need to know about Spring Boot and embedded DBs. I see absolutely no reason to use the scope of dependency other than test, unless you actually intentionally configure an embedded DB for your application runtime. Believe it or not H2 jar alone takes 1.8M inside your fat jar. In the world on granular microservices, serverless and lambda functions it does matter what you put inside your apps.
I would also recommend checking the options in #AutoConfigureTestDatabase. I use it with #SpringBootTest, but it can also be used with some other annotations, namely #DataJpaTest, both mentioned above:
You will need to use Spring Profiles - https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-set-active-spring-profiles
You will define an active profile using "spring.profiles.active = development" and then including H2 in your development profile.
The examples use YAML, but they work in standard properties files as well.

Jersey with Spring 4 Dependency Injection

I am to use Dependency Injection of Spring framework version 4. I have seen that the Jersey has its DI with plugin
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.12</version>
</dependency>
Is Jersey's DI of Spring recommended or is there special reason to use it? What if Spring 4 DI is used independently ?
Also please let me know any step by step learning source to integration Spring DI with Jersey ?
The jersey-spring3 extension is not a stand-alone Dependency Injection feature, it's just an extension which makes Jersey aware of Spring's managed beans.
From Jersey - Spring DI:
Jersey provides an extension to support Spring DI. This enables Jersey to use Spring beans as JAX-RS components (e.g. resources and providers) and also allows Spring to inject into Jersey managed components.
...
The above module does not add any transitive dependency to Spring modules, so you will need to add Spring 3 dependencies explicitly into your dependency list.
So if you want to use Jersey with Spring you need jersey-spring3 and all the Spring dependencies you normally use.
By the way, the jersey-spring3 extension is compiled against Spring 3, but should work with Spring 4. See Using Jersey-spring with Spring 4.0 for reference.
You should add jersey-spring3.jar first like the document in jersey website.
For this step by step learning source to integration Spring DI with Jersey, you can do like this when you start up you application debug the application.
Find ServletContainer.class and set a breakpoint in init() function, as this you can find this step by step.

Categories

Resources