Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Upgrade Java runner with better support #383

Closed
jhoffner opened this issue Apr 21, 2017 · 8 comments
Closed

Upgrade Java runner with better support #383

jhoffner opened this issue Apr 21, 2017 · 8 comments

Comments

@jhoffner
Copy link
Member

Java needs a number of improvements. Before we can embark on many of them, we initially will need to move Java off of the JVM-runner so that we can support it better.

@javatlacati
Copy link
Contributor

Can we have Spring (core) instead of Spring boot?

sample Spring hello world:

//config class
public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

//main app class

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
   }
}

you can test it in the console like a normal java program ( without other spring libraries it mostly does Dependency Injection ) .

sample Spring boot hello world:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class DemoApplication {

    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }

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

you can test it from your browser and check that the server that says hello world has been condigured at localhost:8080.

@jhoffner
Copy link
Member Author

I'm not a Java/Spring guy. Is spring core just something that I need to include as its own dependency within Gradle? It looks like without Spring Boot we would need to be able to define a Beans.xml file correct? How does Spring core work with testing? With Spring boot I was able to get Spring test successfully working and things seemed pretty easy to work with.

This currently works:

package hello;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class HttpRequestTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void greetingShouldReturnDefaultMessage() throws Exception {
        assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/",
                String.class)).contains("Hello World");
    }
}

@javatlacati
Copy link
Contributor

Yes.. but you are creating a rest webservice with an embedded webserver for every run at a randomly chosen port.
Spring boot is actually based on Spring(core) and is specialized for faster web application development, let's say that is something like ruby on rails something very powerful and you can create a server and serve a hello world page or anything you want, but perhaps that's a very specialized task for the codewars platform purposes ( And I think it's absolutely great but it coould be great to slart with something more mundane ).

Annotation configuration is prefered over XML configuration.

You can use SpringJUnit4ClassRunner to load and run context.

So lets say we have our context config as follows:

package com.sompeackage.configuration;

import org.springframework.context.annotation.ComponentScan;
//config with annotations instead of xml
import org.springframework.context.annotation.Configuration;


//will look for classes to bind in package com.somepackage.services
@Configuration
@ComponentScan(basePackages = {"com.somepackage.services"})
public class AppConfig {
}

At services we can have the class to be injected (let's say it's the equivalent for preloaded code if you use with a normal file or the test target if no as in this case)

package com.somepackage.services;

import org.springframework.stereotype.Service;

//will be registered as "service" and automatically instantiated
@Service("service")
public class MyService{
    //instance method
    public String Helloworld() {
        return "Hello World!";
    }
}

And out test code for the service could be something like:

//on test folder of course
package com.somepackage.services;

//use junit4 with spring
@RunWith(SpringJUnit4ClassRunner.class)
// use configuration context to search for services automatically
@ContextConfiguration(classes = {AppConfig.class})
public class MyServiceTest {
    // automatically search for instances in the "context"
    @Autowired
     //search for instances registered with the name "service" instead of default "myService"
    @Qualifier("service")
    MyService service;

    //common junit test
    @Test
    public void helloTest() {
        assertEquals(service.Helloworld(), "Hello World!");
    }
}

The magic of Spring is that you could easily integrate any service in common code as follows:

//on source folder of course
package com.somepackage.controlleroranything;

public class HelloWorld {
    // automatically search for instances in the "context"
    @Autowired
     //search for instances registered with the name "service" instead of default "myService"
    @Qualifier("service")
    MyService service;

    public static void main(String args[]) {
        System.out.println(service.Helloworld());
    }
}

Hope this code caan be useful to you.

@jhoffner
Copy link
Member Author

Thanks, that is very helpful. So can this be handled simply by providing spring-core as a loadable dependency?

@jhoffner
Copy link
Member Author

Actually it looks like core and context should already be loaded, via Spring boot... so it seems like you can use boot or not use boot - both are supported. Is this correct?

@javatlacati
Copy link
Contributor

As you may see both projects are separated (even if spring boot uses internally the spring framework) but is more like a crystal on rails than a ruby on rails.

Certainly it configures all to ease the learning curve, but there are some subtle differences with spring framework applications i.e. with spring-webmvc, and the most important for me is that testing is performed very differently.

@jhoffner
Copy link
Member Author

I'm trying to understand the action item here. Both are supported as of now AFAIKT. Simply include "spring" as a reference and use whichever you prefer. Have you seen the spring PR that I recently merged?

@kazk
Copy link
Member

kazk commented Feb 22, 2019

Closing because the original issue is no longer relevant.

@kazk kazk closed this as completed Feb 22, 2019
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

No branches or pull requests

3 participants