Unusual behavior in a Java application deployed to tomcat

I deployed the Spring 4 application to the tomcat server, which is hosted in the Digital Ocean cloud, CentOS VM. The application is a mobile backend application, mainly the Rest API. JDK - openjdk version "1.8.0_111" OpenJDK working environment (build 1.8.0_111-b15) OpenJDK 64-Bit Server VM (build 25.111-b15, mixed mode) together with Apache Tomcat / 7.0.54 and the database is located in another virtual the car.

The application works as usual, but sometimes an unusual behavior is observed in the application. I logged every call REST Controllerfrom frontend (i.eMobile) using Log4j, and I use tail -f /usr/share/tomcat/logs/someapp/info.logto view the log runtime. Frontend APIs are usually asynchronous, and server behavior is as expected. But when testing on some device, the behavior is strange. When a device calls an API call, the log does not print an API call record, and the response is also incorrect. So I made a remote debugging from the Eclipse, but very slow (it takes a few minutes to get to the breakpoint, do not know how fast to do), I have JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Djava.awt.headless=true -Xmx3072m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -Xdebug -agentlib:jdwp=transport=dt_socket,address=8090,server=y,suspend=n"totomcat.conf. Even when the debugger is connected, the behavior is the same, the answer is present in the external interface, but not the log, and also does not fall on the breakpoint and incorrect data. But when the same API is called from Postman, it hits, and a log is also written, and the data is also correct. An external call is asynchronous and simultaneously calls several APIs. I tried to reproduce the behavior on my local machine, but could not replicate, the behavior will be as expected, and the response data is also correct.

But when a single / (or less) call is made, the API call is recorded as expected, very strange.

Does the JVM do some caching? or does it give this behavior to multiple API calls at the same time? Or do you need some kind of configuration?

Help, suggestions .. appreciated.

My code: Controller:

@RequestMapping(value="/get_VIP_requests/{fbId}", method = RequestMethod.GET)
    public ResponseEntity<ServiceResponse> getVIPRequests(@RequestHeader HttpHeaders headers,@PathVariable("fbId") Long fbId){
        try {
            HeaderDto headerDto = new HeaderDto();
            GeneralUtil.fillHeaderCredential(headers, headerDto, GeneralUtil.ACCESS_TOKEN);
            ServiceResponse serviceResponse = new ServiceResponse("Users have been retrieved successfully");
            serviceResponse.addParam("users",clientService.listVIPRequests(fbId));
            return new ResponseEntity<ServiceResponse>(serviceResponse, HttpStatus.OK);

        } catch (Exception e){
            GeneralUtil.logError(log, "Error Occurred while getting users", e);
            HttpHeaders httpHeaders = ServiceResponse.generateRuntimeErrors(e);
            return new ResponseEntity<ServiceResponse>(httpHeaders, HttpStatus.EXPECTATION_FAILED);
        }
    }

Service:

@Override
    public List<UserEntity> listVIPRequests(Long vipFbId) throws Exception {

        List<UserEntity> requesterList = myVIPDao.listVIPRequestsNormal(vipFbId);

        List<UserEntity> blockedUsers = userFriendshipDao.listUsersByStatus(vipFbId, UserFriendshipStatus.BLOCKED);
        List<UserEntity> usersWhoHaveBlockedMe = userFriendshipDao.listUsersWhoHaveBlockedMe(vipFbId, UserFriendshipStatus.BLOCKED);
        requesterList.removeAll(blockedUsers);
        requesterList.removeAll(usersWhoHaveBlockedMe); 

        List<UserEntity> responseList = new ArrayList<>();
        for (UserEntity user : requesterList) {
            UserEntity returnUser = new UserEntity();
            returnUser.setEntityId(user.getEntityId());
            returnUser.setFacebookId(user.getFacebookId());
            returnUser.setFullName(user.getFullName());
            returnUser.setEmail(user.getEmail());
            returnUser.setGender(user.getGender());
            returnUser.setPushNotificationStatus(null);
            returnUser.setProfileImageUrl(user.getProfileImageUrl());
            returnUser.setInfo(user.getInfo());
            responseList.add(returnUser);
        }

        List<BusinessEntity> businessRequesterList = myVIPDao.listVIPRequestsBusiness(vipFbId);

        if(businessRequesterList!=null & !businessRequesterList.isEmpty()){
            businessRequesterList.stream().forEach(b -> {
                UserEntity returnUser = new UserEntity();
                returnUser.setBusinessId(b.getEntityId());                    //To identify if the request is from business a/c or normal a/c                                                                  
                returnUser.setEntityId(b.getEntityId());
                returnUser.setFacebookId(b.getOwner().getFacebookId());
                returnUser.setFullName(b.getBusinessName());
                returnUser.setEmail(b.getWebUrl());
                returnUser.setGender(Gender.Male);
                returnUser.setPushNotificationStatus(null);
                returnUser.setProfileImageUrl(b.getProfileImage());
                returnUser.setInfo(b.getDescription());
                responseList.add(returnUser);
            });
        }
        return responseList;
    }

DAO:

@SuppressWarnings("unchecked")
    @Override
    public List<UserEntity> listVIPRequestsNormal(Long vipFbId) throws Exception {

        Criteria criteria = getCurrentSession().createCriteria(MyVipEntity.class, "v1");
        criteria.createAlias("v1.friend", "vip");
        criteria.createAlias("v1.organizer", "organizer");
        criteria.add(Restrictions.eq("v1.requestStatus", VIPStatus.REQUESTED));
        criteria.add(Restrictions.eq("vip.facebookId", vipFbId));  
        criteria.add(Restrictions.isNull("v1.business"));
        criteria.setProjection(Projections.property("organizer"));
        criteria.addOrder(Order.asc("organizer.fullName"));

        return (List<UserEntity>) criteria.list();
    }

@SuppressWarnings("unchecked")
    @Override
    public List<BusinessEntity> listVIPRequestsBusiness(Long vipFbId) throws Exception {

        Criteria criteria = getCurrentSession().createCriteria(MyVipEntity.class, "v1");
        criteria.createAlias("v1.friend", "vip");
        criteria.createAlias("v1.business", "business");
        criteria.add(Restrictions.eq("v1.requestStatus", VIPStatus.REQUESTED));
        criteria.add(Restrictions.eq("vip.facebookId", vipFbId));  
        criteria.add(Restrictions.isNotNull("v1.business"));
        criteria.setProjection(Projections.property("v1.business"));
        criteria.addOrder(Order.asc("business.businessName"));

        return (List<BusinessEntity>) criteria.list();
    }
+4
2

Cache-Control.

, Cache-Control: no-cache, no-store, max-age=0, must-revalidate, /.

- . Cache-Control , spring, .

Mozilla : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control

+2

, ? @ResponseBody .

+1

Source: https://habr.com/ru/post/1670309/


All Articles