Bonjour,

j'utilise TOMCAT pour déployer une application SpringBoot / Java. j'ai implémenté un web service dans cette application

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
    @PostMapping("/removeRoles")
    public String removeRoles(@RequestBody String path, HttpServletRequest request, HttpServletResponse response) throws RecordNotFoundException, CustomException, NotFoundException, IOException {
 
        String decodedPath = "";
        try {
            decodedPath = java.net.URLDecoder.decode(path, StandardCharsets.UTF_8.name());
            decodedPath = decodedPath.substring(0,decodedPath.length()-1);
        } catch (UnsupportedEncodingException e) {
            // not going to happen - value came from JDK's own StandardCharsets
        }
        DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss");
        String currentDateTime = dateFormatter.format(new Date());
        Path javaPath = Paths.get(decodedPath + "\\log-removeRoles-"+currentDateTime+".txt");
        try {
            File myObj = new File(decodedPath + "\\log-removeRoles-"+currentDateTime+".txt");
            if (myObj.createNewFile()) {
                System.out.println("File created: " + myObj.getName());
            } else {
                System.out.println("File already exists.");
            }
        } catch (IOException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
 
            scriptService.removeRoles(javaPath);
 
        return "SUCCESS";
    }
Le service removeRoles( String javaPath) est le suivant

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    public void removeRoles(Path javaPath) throws RecordNotFoundException, CustomException, NotFoundException, IOException {
        PrintStream originalOut = System.out;  // original PrintStream
        PrintStream out = new PrintStream(Files.newOutputStream(javaPath), true); // new PrintSream to redirect System.out.println towards file which path is "javaPath"
        System.setOut(out);
        List<RequestEntity> allRequest = requestRepository.findAllByStatusDone();  // find all requests which status is DONE
        System.out.println("TOTAL COUNT="+allRequest.size());  // print the size of the collection
        System.setOut(originalOut);
        RoleEntity role;
        String groupAD;
        List<EmployeeDto> listEmployees;
        List<String> findADEmployeesByAffectedUser;
        int count = 1;
        RequestHasStatus requestHasStatus;
        StatusEntity statusEntityREMOVED = requestService.readStatusByName(Status.REMOVED.getStat());
        EmployeeEntity userTrigger= getEmployee("mdupont", "Michel", "DUPONT", "michel.dupont@organization.fr");
        for (RequestEntity requestEntity : allRequest) {
            System.setOut(originalOut);
            role = requestEntity.getRole();
            groupAD = role.getGroupAD();
            listEmployees = lDAPService.getEmployeesResults(groupAD);  // request the list of employees that belongs to Group "groupAD" in Active Directory
            final RequestEntity requestEntityTemp = requestEntity;
            findADEmployeesByAffectedUser = listEmployees.stream().map((EmployeeDto emp) -> emp.getAccount()).filter((String account) -> account.indexOf(requestEntityTemp.getAffectedUser().getAccountAD()) > -1).collect(Collectors.toList());
            if (findADEmployeesByAffectedUser.isEmpty()) {
                List<RequestHasStatus> listRequestHasStatus = requestHasStatusRepository.getRequestHasStatusByRequestAndStatus(requestEntity.getId(), statusEntityREMOVED.getId()); // list of RequestHasStatus object which identifier is requestEntity.getId() and status is REMOVED
                if (listRequestHasStatus.isEmpty()) {  // if the list is empty
                    requestHasStatus = new RequestHasStatus();
                    requestHasStatus.setRequest(requestEntity);
                    requestHasStatus.setStatus(statusEntityREMOVED);
                    requestHasStatus.setReason("request that are in App and not in AD in September 2023");
                    requestHasStatus.setDate(new Date());
                    requestHasStatus.setTriggeredBy(userTrigger);
                    requestHasStatus = requestHasStatusRepository.saveAndFlush(requestHasStatus);  // create RequestHasStatus Object with status REMOVED
                    requestEntity.getRequestHasStatuses().add(requestHasStatus);
                    requestEntity.setCurrentStatusId(statusEntityREMOVED.getId());
                    requestEntity = requestRepository.saveAndFlush(requestEntity); // update requestEntity with the new status
                    System.setOut(out);
                    System.out.println("COUNT=" + count + "  Account User=" + requestEntity.getUser().getAccountAD() + "  Role Group AD=" + groupAD + " Status REMOVED ("+requestHasStatus.toString()+") ADDED "); // print in the file which path is javaPath
                } else {
                    System.setOut(out);
                    System.out.println("COUNT=" + count + "  Account User=" + requestEntity.getUser().getAccountAD() + "  Role Group AD=" + groupAD + "EXISTS in Active Directory");
                }
            }
            System.setOut(out);
            System.out.println("COUNT=" + count);
            count++;
        }
    }
son but est de rajouter un statut REMOVED pour les requêtes qui sont dans App et pas dans l'Active Directory


J'ai un client Java qui est le suivant

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    public static void main(String[] args) {

            try {
                String currentLocation = System.getProperty("user.dir");
                System.out.println("CURRENT LOCATION="+currentLocation);

                URL url = new URL("http://ip:8080/removeRoles");
 
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Accept", "application/json");
                OutputStream os = conn.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
                osw.write(currentLocation);
                osw.flush();
                osw.close();
                os.close();  //don't forget to close the OutputStream

                if (conn.getResponseCode() != 200) {  // the request is sent at this line
                    throw new RuntimeException("Failed : HTTP error code : "
                            + conn.getResponseCode());
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(
                        (conn.getInputStream())));

                String output;
                System.out.println("Output from Server .... \n");
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
                }

                conn.disconnect();

            } catch (MalformedURLException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            }
        
}

MON PROBLEME
--------------------
Quand je déploie la partie backend sous TOMCAT et regarde tomcat.exe dans le task manager, la mémoire utilisée se stabilise à environ 350.000 K.
Quand je lance le client (création d'une connection à partir de HttpURLConnection ), la mémoire du processus tomcat.exe augmente de 2.000K to 10.000K chaque seconde jusqu'à ce que TOMCAT crash
Quel peut être la cause de la fuite de mémoire ?