4

currently I am trying to add spring boot to an existing project.
This project is a standalone jar that successfully uses spring jpa and hibernate. But because the application must be able to receive and send json files, I thought that spring boot would be the best option.

Therefore I added the following dependency to my pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>

And set up a little RequestMapping as a test

@Controller
public class RequestMappingController {
    @RequestMapping("/")
    @ResponseBody
    public String myAction() {
        return "Hello World !";
    }
}

Now I have the problem, that all my sources (this, this and this) are telling me to set up the main method next.
Something like

public static void main(String[] args) {
    SpringApplication.run(Main.class, args);
}

But I am not able to change that method. My architecture uses a main jar file that loads components and plugins as jar files. And the main jar file is downloaded and is not programmed by me.

main.jar          (downloaded)
|- plugin1.jar    (programmed by me)
|- plugin2.jar    (programmed by me)
|- ...

I am not using any xml files (except the pom.xml file of course) to configure spring. In myplugin1.jarthere is a JpaConfig Class with all the important spring enabling annotations (@EnableScheduling,@EnableAsync, transactionmanagement, component scan,@Configuration, jpa repository enabling, ...)
I recognices that there is also a annotation
@SpringBootConfiguration` and because my plugin1 is able to activate all current implemented spring components in this Configuration class, maybe I can set up spring boot there as well? (is there a way? or some other way with a second configuration class?)

And that is my question: how can I enable spring boot within this existing project structure without changing the main(String[] args) method?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
toddeTV
  • 1,447
  • 3
  • 20
  • 36

1 Answers1

3

add this to your pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.2.RELEASE</version>
</parent>

Edit: the POM:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
    </parent>

    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

That is you need to give spring boot a connector and also a application.properties on connection information of the database. For example:

# database
spring.datasource.url= jdbc:mysql://****
spring.datasource.username=****
spring.datasource.password=****

#ddl generation
spring.jpa.hibernate.ddl-auto=update

# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.testOnBorrow=true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1

# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.max-wait=10000

# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.max-active=50

# Show or not log for each sql query
spring.jpa.show-sql = true

# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
dumb_terminal
  • 1,815
  • 1
  • 16
  • 27
  • 1
    When I do this, I only get `org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in testProject.JpaConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl$Work` – toddeTV Oct 02 '16 at 12:41
  • with `Caused by: java.lang.ClassNotFoundException: org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl$Work` – toddeTV Oct 02 '16 at 12:41
  • ok, so it seems I am missing a lot of properties. Will it be a problem to add multiple database configurations? Because currently for example I use a BoneCPDataSource for username and password for the database and a jpaProperty for the `hibernate.show_sql` and other settings. Now you want me to add all these configurations a second time. not for hibernate, but for spring itself. So I will have everything twice: double username, double password, ... Will this be a problem in performance? and why does spring boot not use the existing hibernate connection? – toddeTV Oct 02 '16 at 14:34
  • database host username passwor connector class is enough, also in pom.xml use your connector for your database instead of mysql, also more information of your current project layout will be helpful. – dumb_terminal Oct 02 '16 at 14:51
  • I have a `mysql:mysql-connector-java:6.0.3` in my project (for hibernate and jpa). So i did not changed this. FOr spring boot I now have `org.springframework.boot:spring-boot-starter-web:1.4.0`, `org.springframework.boot:spring-boot-starter-data-jpa:1.4.0` and `org.hibernate:hibernate-core:4.3.11.Final` (don't know why I need `hibernate-core`, but without I get errors. Besides this, I also have the `hibernate-entitymanager`). Also I have **no** `application.properties`. When I now start the application, I get no error's and all my old commands/structure is working. But with – toddeTV Oct 02 '16 at 15:37
  • `http://127.0.0.1:8080` there is no `Hello world !` output. So my request mapping is not working. So am I missing something? – toddeTV Oct 02 '16 at 15:37
  • put the same request mapping on the controller as wel – dumb_terminal Oct 02 '16 at 15:39
  • could you share more of your code so that I can have a look at the total structure ? uploa it somewhere and give me a link. – dumb_terminal Oct 02 '16 at 16:07
  • At first I want to thank you for all your time. And second: yes, I wrote the most important parts of the projects together and uploaded it here: http://79.214.225.40:9911/ I hope this way is acceptable for you because I do not know a good website to share code in this way. I also added some basic information of the projects (structure, architecture, compiling, ...) besides the code. If you need more information or code, just let me know. Currently I uploaded all the "new" code from the project since I added spring-boot and all things I thought they could be interesting – toddeTV Oct 02 '16 at 16:55
  • ok not much help there, last attempt, have you @SpringBootApplication annotation on the class which contains main ? – dumb_terminal Oct 02 '16 at 17:03
  • that's the problem why I posted my question on stackoverflow: no, because the main class is not part of my own projects. I write a component/plugin for a program that loads it as a jar file (see original question). I hoped that there is an other way of activating it, because there are so many configuration annotations in spring. – toddeTV Oct 02 '16 at 17:20
  • You have to enable component scan in order to enable controllers http://stackoverflow.com/questions/20551217/spring-support-for-controller-given-by-contextcomponent-scan-vs-mvcannot – dumb_terminal Oct 02 '16 at 17:33