0

I have a ear which consist one ejb and one war module, and other local jar dependencies such as dao and services.

I've placed project on github https://github.com/SunPj/spring-load-time-weaving

I use spring load time weaving. My dao application context consists following lines

<tx:annotation-driven mode="aspectj"/>
<context:load-time-weaver aspectj-weaving="on"/>

My cache context has<cache:annotation-driven mode="aspectj"/>

My web module has a controller

package ru.test.web;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import ru.test.service.TestService;

import java.util.Map;

@Controller
public class TestController {

    @Autowired
    TestService testService;

    @RequestMapping("/userlist")
    public String userList(Map<String, Object> model) {
        String st = ArrayUtils.toString(testService.getUsers());
        model.put("text", st);
        return "main";
    }

    @RequestMapping("/remove-user")
    public String removeUser(@RequestParam("userId") int userId, Map<String, Object> model) {
        testService.removeUser(userId);
        model.put("text", "Removed userid = "+userId);
        return "main";
    }

    @RequestMapping("/remove-user-ex")
    public String removeUserEx(@RequestParam("userId") int userId, Map<String, Object> model) {
        try {
            testService.removeUserWithException(userId);
        } catch (RuntimeException e){
            model.put("text", "Exception = "+e.getMessage());
        }

        return "main";
    }

    @RequestMapping("/random")
    public String random(Map<String, Object> model) {
        String s = new String();
        for (int i = 0; i< 100; i++){
            s = s + +testService.getRandom()+",   ";
        }
        model.put("text", "Random = "+s);

        return "main";
    }

    @RequestMapping({"/", "/home"})
    public String index(Map<String, Object> model) {
        model.put("text", "Home page!");
        return "main";
    }

    @RequestMapping("/user-cache-evict")
    public String userCacheEvict(Map<String, Object> model) {
        testService.userCacheEvict();
        model.put("text", "user cache evicted!");
        return "main";
    }

    @RequestMapping("/data-cache-evict")
    public String dataCacheEvict(Map<String, Object> model) {
        testService.dataCacheEvict();
        model.put("text", "data cache evicted!");
        return "main";
    }
}

Servise looks like

@Service
@Transactional
public class TestServiceImpl implements TestService {

    @Autowired
    private TestDao testDao;

    @Override
    public String getUsers() {
        return testDao.showUsers() + "( real count = "+testDao.getRealUsersCount()+")";
    }

    @Override
    public void removeUser(int userId) {
        testDao.removeUser(userId);
    }

    @Override
    public void removeUserWithException(int userId) {
        testDao.removeUser(userId);
        throw new RuntimeException("ololo");
    }

    @Override
    public int getRandom() {
        return testDao.getRandom();
    }

    @Override
    public void userCacheEvict() {
        testDao.userCacheEvict();
    }

    @Override
    public void dataCacheEvict() {
        testDao.dataCacheEvict();
    }

    @Override
    public int showUsers() {
        return 1;
    }
}

Dao

@Repository
public class TestDaoImpl extends AbstractDao implements TestDao {

    @Override
    public void removeUser(int id) {
        getJdbcTemplate().execute("DELETE FROM TABLE1 WHERE id = " + id);
    }

    @Override
    public String showUsers() {
        String users = ArrayUtils.toString(getJdbcTemplate().queryForList("SELECT name FROM TABLE1", String.class));

        return users + ":" + getCachedUsersCount();
    }

    @Override
    @Cacheable(value = "User")
     public int getCachedUsersCount(){
        int cnt = getJdbcTemplate().queryForInt("SELECT count(*)name FROM TABLE1");
        return cnt;
    }

    @Override
    public int getRealUsersCount(){
        int cnt = getJdbcTemplate().queryForInt("SELECT count(*)name FROM TABLE1");
        return cnt;
    }

    @Override
    @CacheEvict(value = "User", allEntries = true)
    public void userCacheEvict(){
    }

    @Override
    @CacheEvict(value = "PermanentData", allEntries = true)
    public void dataCacheEvict(){
    }

    @Override
    @Cacheable(value = "PermanentData")
    public int getRandom() {
        return new Random().nextInt();
    }
}

All works fine while ejb does not have a service dependency. As soon as i added a service dependency to ejb module (pom of some-ejb) transaction stopped work.

In github last 2 commits (commit 973f48a9e0db11edc3675fd09b6930f05b98afc9 and commit e7d280cb93b2303bfcfbd5cd0b55d24b002be8fc) show both working and no working situation.

kraken
  • 484
  • 7
  • 18
  • 1
    Using the EJB triggers eager loading of the service class and with a classloader that isn't supporting LTW (as that is only enabled as soon as the context is being loaded, which is after the EJB stuff). – M. Deinum Jun 10 '14 at 08:27
  • How can i fix it? In websphere i've changed a `starting weight` values, but it doesn't help me – kraken Jun 10 '14 at 08:55

1 Answers1

0

Spring Framework has own spring container and it is manages all transaction internally and also it is provide the dependency injection and IoC so there was no need of EJB.You can put your EJB logic in also spring no need to deploy EJB.

That's why you only have to add at your applicationContext.xml the following tags: and to scan the packages.

  • Thanks, but i have existing ejb module with more code and i don't want to change any written code. I've created github project just for example – kraken Jun 10 '14 at 10:03