    @Async
//    @Transactional(propagation = Propagation.REQUIRED)
    public Future<Void> groupSearch(UserPrincipal userPrincipal, List<File> files, HttpSession session,
                                    SearchParameters userParameters,
                                    boolean withOntologyLevels, boolean sendResultsToEmail) throws TimeoutException {

//        LOGGER.info("Group search has started");

        try {
            final List<SearchResultDTO> groupSearchDTOList = new ArrayList<>();
            session.setAttribute(ControllerUtils.GROUP_SEARCH_RESULTS_ATTRIBUTE_NAME, groupSearchDTOList);

            // Calculate total number of spectra
            long totalSteps = files.stream()
                    .map(File::getSpectra).filter(Objects::nonNull)
                    .mapToInt(List::size)
                    .sum();

            if (totalSteps == 0) {
                LOGGER.warn("No query spectra for performing a group search");
                session.setAttribute(ControllerUtils.GROUP_SEARCH_RESULTS_ATTRIBUTE_NAME, groupSearchDTOList);
                return new AsyncResult<>(null);
            }

            long startTime = System.currentTimeMillis();

            boolean showSessionEndedMessage = true;
            int spectrumCount = 0;
            int progressStep = 0;
            float progress = 0F;
            int position = 0;
            for (int fileIndex = 0; fileIndex < files.size(); ++fileIndex) {

                File file = files.get(fileIndex);
                List<Spectrum> spectra = file.getSpectra();
                if (spectra == null) continue;
                for (int spectrumIndex = 0; spectrumIndex < spectra.size(); ++spectrumIndex) {  // Spectrum querySpectrum : file.getSpectra()
                    if(System.currentTimeMillis() - startTime > 6 * 60 * 60 * 1000)
                    {
                        session.setAttribute(ControllerUtils.GROUP_SEARCH_ERROR_ATTRIBUTE_NAME, "Group search timed out");
                        throw new TimeoutException("Group search timed out");
                    }

                    Spectrum querySpectrum = spectra.get(spectrumIndex);

                    if (Thread.currentThread().isInterrupted()) break;

                    SearchParameters parameters =
                            SearchParameters.getDefaultParameters(querySpectrum.getChromatographyType());
                    parameters.merge(userParameters);
//                    parameters.setLimit(10);

                    List<SearchResultDTO> individualSearchResults;
                    try {
                        individualSearchResults = (withOntologyLevels)
                                ? spectrumSearchService.searchWithOntologyLevels(userPrincipal, querySpectrum, parameters)
                                : spectrumSearchService.searchConsensusSpectra(userPrincipal, querySpectrum, parameters);
                    } catch (IllegalSpectrumSearchException e) {
                        LOGGER.error(String.format("Error when searching %s [%d]: %s",
                                querySpectrum.getName(), querySpectrum.getId(), e.getMessage()));
                        SearchResultDTO searchResultDTO = new SearchResultDTO(querySpectrum);
                        searchResultDTO.setErrorMessage(e.getMessage());
                        individualSearchResults = Collections.singletonList(searchResultDTO);
                    }

                    if (individualSearchResults.isEmpty())
                        individualSearchResults.add(new SearchResultDTO(querySpectrum));

                    for (SearchResultDTO searchResult : individualSearchResults) {
                        searchResult.setPosition(1 + position++);
                        searchResult.setQueryFileIndex(fileIndex);
                        searchResult.setQuerySpectrumIndex(spectrumIndex);
                    }

                    if (Thread.currentThread().isInterrupted()) break;

                    progress = (float) ++progressStep / totalSteps;
                    groupSearchDTOList.addAll(individualSearchResults);
                    try {
                        session.setAttribute(ControllerUtils.GROUP_SEARCH_RESULTS_ATTRIBUTE_NAME, groupSearchDTOList);
                        session.setAttribute(ControllerUtils.GROUP_SEARCH_PROGRESS_ATTRIBUTE_NAME, progress);
                    } catch (IllegalStateException e) {
                        if (sendResultsToEmail) {
                            if (showSessionEndedMessage) {
                                LOGGER.warn("It looks like the session has been closed.");
                                showSessionEndedMessage = false;
                            }
                        } else {
                            LOGGER.warn("It looks like the session has been closed. Stopping the group search.");
                            return new AsyncResult<>(null);
                        }
                    }

                    if (++spectrumCount % 100 == 0) {
                        long time = System.currentTimeMillis();
                        LOGGER.info(String.format(
                                "Searched %d spectra with the average time %.3f seconds per spectrum",
                                spectrumCount, 1E-3 * (time - startTime) / spectrumCount));
                    }
                }
            }

            if (!groupSearchDTOList.isEmpty() && sendResultsToEmail && userPrincipal != null) {
                String tmpdir = System.getProperty("java.io.tmpdir");
                String date = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").format(LocalDateTime.now());
                String filePath = Paths.get(tmpdir, String.format("simple_output_%s.xlsx", date)).toString();
                LOGGER.info(String.format("Writing to file '%s'", filePath));

                try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
                    //export file locally
                    exportSearchResultsService.export(fileOutputStream, groupSearchDTOList);
                    //send email with that file
                    emailService.sendEmailWithAttachment(filePath, userPrincipal.getEmail());
                    //delete the local file
                    Path path = FileSystems.getDefault().getPath(filePath);
                    Files.delete(path);

                } catch (NoSuchFileException e) {
                    LOGGER.error(String.format("%s: no such file or directory: %s", filePath, e.getMessage()), e);
                } catch (IOException e) {
                    LOGGER.warn(String.format("Error when writing to file '%s': %s", filePath, e.getMessage()), e);
                }

//                filePath = Paths.get(userHome, String.format("advanced_output_%s.xlsx", date)).toString();
//                LOGGER.info(String.format("Writing to file '%s'", filePath));
//                try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
//                    exportSearchResultsService.exportAll(fileOutputStream, groupSearchDTOList);
//                } catch (IOException e) {
//                    LOGGER.warn(String.format("Error when writing to file '%s': %s", filePath, e.getMessage()), e);
//                }
            }

        } catch (Throwable t) {
            LOGGER.error(String.format("Error during the group search: %s", t.getMessage()), t);
            session.setAttribute("GROUP_SEARCH_ERROR", t.getMessage());
            throw t;
        }

        if (Thread.currentThread().isInterrupted())
            LOGGER.info("Group search is cancelled");

        return new AsyncResult<>(null);
    }

    @Async
//    @Transactional(propagation = Propagation.REQUIRED)
    public Future<Void> groupSearch(UserPrincipal userPrincipal, List<File> files, HttpSession session,
                                    SearchParameters userParameters,
                                    boolean withOntologyLevels, boolean sendResultsToEmail) throws TimeoutException {

//        LOGGER.info("Group search has started");

        try {
            final List<SearchResultDTO> groupSearchDTOList = new ArrayList<>();
            session.setAttribute(ControllerUtils.GROUP_SEARCH_RESULTS_ATTRIBUTE_NAME, groupSearchDTOList);

            // Calculate total number of spectra
            long totalSteps = files.stream()
                    .map(File::getSpectra).filter(Objects::nonNull)
                    .mapToInt(List::size)
                    .sum();

            if (totalSteps == 0) {
                LOGGER.warn("No query spectra for performing a group search");
                session.setAttribute(ControllerUtils.GROUP_SEARCH_RESULTS_ATTRIBUTE_NAME, groupSearchDTOList);
                return new AsyncResult<>(null);
            }

            long startTime = System.currentTimeMillis();

            boolean showSessionEndedMessage = true;
            int spectrumCount = 0;
            int progressStep = 0;
            float progress = 0F;
            int position = 0;
            for (int fileIndex = 0; fileIndex < files.size(); ++fileIndex) {

                File file = files.get(fileIndex);
                List<Spectrum> spectra = file.getSpectra();
                if (spectra == null) continue;
                for (int spectrumIndex = 0; spectrumIndex < spectra.size(); ++spectrumIndex) {  // Spectrum querySpectrum : file.getSpectra()
                    if(System.currentTimeMillis() - startTime > 6 * 60 * 60 * 1000)
                    {
                        session.setAttribute(ControllerUtils.GROUP_SEARCH_ERROR_ATTRIBUTE_NAME, "Group search timed out");
                        throw new TimeoutException("Group search timed out");
                    }

                    Spectrum querySpectrum = spectra.get(spectrumIndex);

                    if (Thread.currentThread().isInterrupted()) break;

                    SearchParameters parameters =
                            SearchParameters.getDefaultParameters(querySpectrum.getChromatographyType());
                    parameters.merge(userParameters);
//                    parameters.setLimit(10);

                    List<SearchResultDTO> individualSearchResults;
                    try {
                        individualSearchResults = (withOntologyLevels)
                                ? spectrumSearchService.searchWithOntologyLevels(userPrincipal, querySpectrum, parameters)
                                : spectrumSearchService.searchConsensusSpectra(userPrincipal, querySpectrum, parameters);
                    } catch (IllegalSpectrumSearchException e) {
                        LOGGER.error(String.format("Error when searching %s [%d]: %s",
                                querySpectrum.getName(), querySpectrum.getId(), e.getMessage()));
                        SearchResultDTO searchResultDTO = new SearchResultDTO(querySpectrum);
                        searchResultDTO.setErrorMessage(e.getMessage());
                        individualSearchResults = Collections.singletonList(searchResultDTO);
                    }

                    if (individualSearchResults.isEmpty())
                        individualSearchResults.add(new SearchResultDTO(querySpectrum));

                    for (SearchResultDTO searchResult : individualSearchResults) {
                        searchResult.setPosition(1 + position++);
                        searchResult.setQueryFileIndex(fileIndex);
                        searchResult.setQuerySpectrumIndex(spectrumIndex);
                    }

                    if (Thread.currentThread().isInterrupted()) break;

                    progress = (float) ++progressStep / totalSteps;
                    groupSearchDTOList.addAll(individualSearchResults);
                    try {
                        session.setAttribute(ControllerUtils.GROUP_SEARCH_RESULTS_ATTRIBUTE_NAME, groupSearchDTOList);
                        session.setAttribute(ControllerUtils.GROUP_SEARCH_PROGRESS_ATTRIBUTE_NAME, progress);
                    } catch (IllegalStateException e) {
                        if (sendResultsToEmail) {
                            if (showSessionEndedMessage) {
                                LOGGER.warn("It looks like the session has been closed.");
                                showSessionEndedMessage = false;
                            }
                        } else {
                            LOGGER.warn("It looks like the session has been closed. Stopping the group search.");
                            return new AsyncResult<>(null);
                        }
                    }

                    if (++spectrumCount % 100 == 0) {
                        long time = System.currentTimeMillis();
                        LOGGER.info(String.format(
                                "Searched %d spectra with the average time %.3f seconds per spectrum",
                                spectrumCount, 1E-3 * (time - startTime) / spectrumCount));
                    }
                }
            }

            if (!groupSearchDTOList.isEmpty() && sendResultsToEmail && userPrincipal != null) {
                String tmpdir = System.getProperty("java.io.tmpdir");
                String date = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").format(LocalDateTime.now());
                String filePath = Paths.get(tmpdir, String.format("simple_output_%s.xlsx", date)).toString();
                LOGGER.info(String.format("Writing to file '%s'", filePath));

                try  {
                    FileOutputStream fileOutputStream = new FileOutputStream(filePath);
                    //export file locally
                    exportSearchResultsService.export(fileOutputStream, groupSearchDTOList);
                    //send email with that file
                    emailService.sendEmailWithAttachment(filePath, userPrincipal.getEmail());
                    //delete the local file
                    Path path = FileSystems.getDefault().getPath(filePath);
                    Files.delete(path);

                } catch (NoSuchFileException e) {
                    LOGGER.error(String.format("%s: no such" + " file or directory%n", filePath, e.getMessage()), e);
                }catch (IOException e) {
                    LOGGER.warn(String.format("Error when writing to file '%s': %s", filePath, e.getMessage()), e);
                }

//                filePath = Paths.get(userHome, String.format("advanced_output_%s.xlsx", date)).toString();
//                LOGGER.info(String.format("Writing to file '%s'", filePath));
//                try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
//                    exportSearchResultsService.exportAll(fileOutputStream, groupSearchDTOList);
//                } catch (IOException e) {
//                    LOGGER.warn(String.format("Error when writing to file '%s': %s", filePath, e.getMessage()), e);
//                }
            }

        } catch (Throwable t) {
            LOGGER.error(String.format("Error during the group search: %s", t.getMessage()), t);
            session.setAttribute("GROUP_SEARCH_ERROR", t.getMessage());
            throw t;
        }

        if (Thread.currentThread().isInterrupted())
            LOGGER.info("Group search is cancelled");

        return new AsyncResult<>(null);
    }

Try With Resources try(FileOutputStream fileOutputStream=new FileOutputStream(filePath)) in method public groupSearch(userPrincipal UserPrincipal, files List<File>, session HttpSession, userParameters SearchParameters, withOntologyLevels boolean, sendResultsToEmail boolean) : Future<Void> from class org.dulab.adapcompounddb.site.services.search.GroupSearchService


    public PrivateWebApplication(@Context ServletContext servletContext) {
        HttpClient httpCLient = HttpClient.getInstance();
        Messages messages = Messages.getInstance(null);

        try {
            SearchEngineConfig.createInstance(httpCLient, servletContext, messages);
            try (SearchClient searchClient = new ESClient()) {
                SearchUtils.deleteOrphanIndexes(searchClient);
            } catch (Exception ex) {
                LOGGER.error(
                    "An exception occurred while deleting orphan search indexes.", ex);
            }
        } catch (Exception ex) {
            LOGGER.error("Could not load the eAtlas search engine configuration.", ex);
        }

        this.packages("au.gov.aims.eatlas.searchengine.admin.rest");
        this.property(JspMvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/jsp");
        this.register(JspMvcFeature.class);
    }

    public PrivateWebApplication(@Context ServletContext servletContext) {
        HttpClient httpCLient = HttpClient.getInstance();
        Messages messages = Messages.getInstance(null);

        try {
            SearchEngineConfig.createInstance(httpCLient, servletContext, messages);
            try {
                SearchUtils.deleteOrphanIndexes();
            } catch (Exception ex) {
                LOGGER.error(
                    "An exception occurred while deleting orphan search indexes.", ex);
            }
        } catch (Exception ex) {
            LOGGER.error("The eAtlas search engine could not load its configuration.", ex);
        }

        this.packages("au.gov.aims.eatlas.searchengine.admin.rest");
        this.property(JspMvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/jsp");
        this.register(JspMvcFeature.class);
    }

Try With Resources try(SearchClient searchClient=new ESClient()) in method public PrivateWebApplication(servletContext ServletContext) from class au.gov.aims.eatlas.searchengine.admin.PrivateWebApplication


    @GET
    @Path("reindex")
    @Produces(MediaType.APPLICATION_JSON)
    public Response reindex(
            @Context HttpServletRequest httpRequest,
            @QueryParam("full") Boolean full, // List of indexes to query
            @QueryParam("token") String token
    ) {
        SearchEngineConfig config = SearchEngineConfig.getInstance();
        String expectedToken = config.getReindexToken();

        CacheControl noCache = new CacheControl();
        noCache.setNoCache(true);

        if (expectedToken == null || expectedToken.isEmpty()) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", "Reindex token not set in Search Engine configuration.");

            String responseTxt = jsonStatus.toString();

            return Response.serverError().entity(responseTxt).cacheControl(noCache).build();
        }

        if (token == null || token.isEmpty()) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", "Parameter token required.");

            String responseTxt = jsonStatus.toString();

            return Response.status(Response.Status.BAD_REQUEST).entity(responseTxt).cacheControl(noCache).build();
        }

        if (!expectedToken.equals(token)) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", "Invalid token provided.");

            String responseTxt = jsonStatus.toString();

            return Response.status(Response.Status.FORBIDDEN).entity(responseTxt).cacheControl(noCache).build();
        }

        // API call - display messages using the LOGGER.
        Messages messages = Messages.getInstance(null);

        try (SearchClient searchClient = new ESClient()) {
            JSONObject jsonStatus = Index.internalReindex(searchClient, full == null ? true : full, messages);

            String responseTxt = jsonStatus.toString();

            // Return the JSON object with an OK status.
            return Response.ok(responseTxt).cacheControl(noCache).build();

        } catch(Exception ex) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", ServletUtils.getExceptionMessage(ex))
                .put("stacktrace", ServletUtils.exceptionToJSON(ex));

            String responseTxt = jsonStatus.toString();

            // Return the JSON object with an ERROR status.
            return Response.serverError().entity(responseTxt).cacheControl(noCache).build();
        }
    }

    @GET
    @Path("reindex")
    @Produces(MediaType.APPLICATION_JSON)
    public Response reindex(
            @Context HttpServletRequest httpRequest,
            @QueryParam("full") Boolean full, // List of indexes to query
            @QueryParam("token") String token
    ) {
        SearchEngineConfig config = SearchEngineConfig.getInstance();
        String expectedToken = config.getReindexToken();

        CacheControl noCache = new CacheControl();
        noCache.setNoCache(true);

        if (expectedToken == null || expectedToken.isEmpty()) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", "Reindex token not set in Search Engine configuration.");

            String responseTxt = jsonStatus.toString();

            return Response.serverError().entity(responseTxt).cacheControl(noCache).build();
        }

        if (token == null || token.isEmpty()) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", "Parameter token required.");

            String responseTxt = jsonStatus.toString();

            return Response.status(Response.Status.BAD_REQUEST).entity(responseTxt).cacheControl(noCache).build();
        }

        if (!expectedToken.equals(token)) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", "Invalid token provided.");

            String responseTxt = jsonStatus.toString();

            return Response.status(Response.Status.FORBIDDEN).entity(responseTxt).cacheControl(noCache).build();
        }

        // API call - display messages using the LOGGER.
        Messages messages = Messages.getInstance(null);

        try {
            JSONObject jsonStatus = Index.internalReindex(full == null ? true : full, messages);

            String responseTxt = jsonStatus.toString();

            // Return the JSON object with an OK status.
            return Response.ok(responseTxt).cacheControl(noCache).build();

        } catch(Exception ex) {
            JSONObject jsonStatus = new JSONObject()
                .put("status", "error")
                .put("message", ServletUtils.getExceptionMessage(ex))
                .put("stacktrace", ServletUtils.exceptionToJSON(ex));

            String responseTxt = jsonStatus.toString();

            // Return the JSON object with an ERROR status.
            return Response.serverError().entity(responseTxt).cacheControl(noCache).build();
        }
    }

Try With Resources try(SearchClient searchClient=new ESClient()) in method public reindex(httpRequest HttpServletRequest, full Boolean, token String) : Response from class au.gov.aims.eatlas.searchengine.rest.Index


    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response search(
            @Context HttpServletRequest httpRequest,
            @QueryParam("q") String q,
            @QueryParam("start") Integer start,
            @QueryParam("hits") Integer hits,
            @QueryParam("wkt") String wkt, // Well Known Text, used for GIS search
            @QueryParam("idx") List<String> idx, // List of indexes used for the summary
            @QueryParam("fidx") List<String> fidx // List of indexes to filter the search results (optional)
    ) {
        HttpSession session = httpRequest.getSession(true);
        Messages messages = Messages.getInstance(session);

        CacheControl noCache = new CacheControl();
        noCache.setNoCache(true);

        if (idx == null) {
            Response.Status status = Response.Status.BAD_REQUEST;
            ErrorMessage errorMessage = new ErrorMessage()
                .setErrorMessage("Invalid request. Missing parameter idx")
                .setStatus(status);
            return Response.status(status).entity(errorMessage.toString()).cacheControl(noCache).build();
        }

        SearchResults results = null;
        try (SearchClient searchClient = new ESClient()) {
            results = Search.paginationSearch(searchClient, q, start, hits, wkt, idx, fidx, messages);

        } catch(Exception ex) {
            String errorMessageStr = String.format("An exception occurred during the search: %s", ex.getMessage());
            messages.addMessage(Messages.Level.ERROR, errorMessageStr, ex);
            Response.Status status = Response.Status.INTERNAL_SERVER_ERROR;
            ErrorMessage errorMessage = new ErrorMessage()
                .setErrorMessage(errorMessageStr)
                .setStatus(status);
            return Response.status(status).entity(errorMessage.toString()).cacheControl(noCache).build();
        }

        if (results == null) {
            String errorMessageStr = "The search engine returned and empty response";
            messages.addMessage(Messages.Level.ERROR, errorMessageStr);
            Response.Status status = Response.Status.BAD_REQUEST;
            ErrorMessage errorMessage = new ErrorMessage()
                .setErrorMessage(errorMessageStr)
                .setStatus(status);
            return Response.status(status).entity(errorMessage.toString()).cacheControl(noCache).build();
        }

        String responseTxt = results.toString();

        // Return the JSON array with an OK status.
        return Response.ok(responseTxt).cacheControl(noCache).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response search(
            @Context HttpServletRequest httpRequest,
            @QueryParam("q") String q,
            @QueryParam("start") Integer start,
            @QueryParam("hits") Integer hits,
            @QueryParam("wkt") String wkt, // Well Known Text, used for GIS search
            @QueryParam("idx") List<String> idx, // List of indexes used for the summary
            @QueryParam("fidx") List<String> fidx // List of indexes to filter the search results (optional)
    ) {
        HttpSession session = httpRequest.getSession(true);
        Messages messages = Messages.getInstance(session);

        CacheControl noCache = new CacheControl();
        noCache.setNoCache(true);

        if (idx == null) {
            Response.Status status = Response.Status.BAD_REQUEST;
            ErrorMessage errorMessage = new ErrorMessage()
                .setErrorMessage("Invalid request. Missing parameter idx")
                .setStatus(status);
            return Response.status(status).entity(errorMessage.toString()).cacheControl(noCache).build();
        }

        SearchResults results = null;
        try {
            results = Search.paginationSearch(q, start, hits, wkt, idx, fidx, messages);

        } catch(Exception ex) {
            String errorMessageStr = String.format("An exception occurred during the search: %s", ex.getMessage());
            messages.addMessage(Messages.Level.ERROR, errorMessageStr, ex);
            Response.Status status = Response.Status.INTERNAL_SERVER_ERROR;
            ErrorMessage errorMessage = new ErrorMessage()
                .setErrorMessage(errorMessageStr)
                .setStatus(status);
            return Response.status(status).entity(errorMessage.toString()).cacheControl(noCache).build();
        }

        if (results == null) {
            String errorMessageStr = "The search engine returned and empty response";
            messages.addMessage(Messages.Level.ERROR, errorMessageStr);
            Response.Status status = Response.Status.BAD_REQUEST;
            ErrorMessage errorMessage = new ErrorMessage()
                .setErrorMessage(errorMessageStr)
                .setStatus(status);
            return Response.status(status).entity(errorMessage.toString()).cacheControl(noCache).build();
        }

        String responseTxt = results.toString();

        // Return the JSON array with an OK status.
        return Response.ok(responseTxt).cacheControl(noCache).build();
    }

Try With Resources try(SearchClient searchClient=new ESClient()) in method public search(httpRequest HttpServletRequest, q String, start Integer, hits Integer, wkt String, idx List<String>, fidx List<String>) : Response from class au.gov.aims.eatlas.searchengine.rest.Search


    public String getOwnerNetworkDeviceName() {
        try {
            NetworkInterface ni = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
            if (ni != null)
                return ni.getDisplayName();
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getOwnerNetworkDeviceName() {
        try {
            NetworkInterface ni = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
            if (ni != null)
                return ni.getDisplayName();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

Merge Catch [catch(SocketException e), catch(UnknownHostException e)] to catch(SocketException|UnknownHostException e) in method public getOwnerNetworkDeviceName() : String from class dev.syster42.framework.api.ServerAPI


    private void resetPieChartOnChangesOfPieChartToggleGroup() {
        pieChartToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> setPieChart());
    }

    private void resetPieChartOnChangesOfPieChartToggleGroup() {
        pieChartToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
            @Override
            public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
                setPieChart();
            }
        });
    }

Replace Anonymous With Lambda at.nicoleperak.client.controllers.FinancialAccountDetailsScreenController.resetPieChartOnChangesOfPieChartToggleGroup.addListener.new ChangeListener<Toggle> with (observable, oldValue, newValue) -> setPieChart() in method private resetPieChartOnChangesOfPieChartToggleGroup() : void from class at.nicoleperak.client.controllers.FinancialAccountDetailsScreenController


    private void loadCategoriesOnSelectionOfRadioButton() {
        transactionTypeToggleGroup.selectedToggleProperty().addListener((observableValue, toggle, radioButton) -> {
            if (radioButton.isSelected()) {
                categoryObservableList.clear();
                CategoryList categoryList = loadCategories();
                categoryObservableList.addAll(categoryList.getCategories());
                categoryComboBox.setItems(categoryObservableList);
                categoryComboBox.setDisable(false);
            }
        });
    }

    private void loadCategoriesOnSelectionOfRadioButton() {
        transactionTypeToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
            @Override
            public void changed(ObservableValue<? extends Toggle> observableValue, Toggle toggle, Toggle radioButton) {
                if (radioButton.isSelected()) {
                    categoryObservableList.clear();
                    CategoryList categoryList = loadCategories();
                    categoryObservableList.addAll(categoryList.getCategories());
                    categoryComboBox.setItems(categoryObservableList);
                    categoryComboBox.setDisable(false);
                }
            }
        });
    }

Replace Anonymous With Lambda at.nicoleperak.client.controllers.TransactionDialogController.loadCategoriesOnSelectionOfRadioButton.addListener.new ChangeListener<Toggle> with (observableValue, toggle, radioButton) -> {if(radioButton.isSelected()){categoryObservableList.clear(); in method private loadCategoriesOnSelectionOfRadioButton() : void from class at.nicoleperak.client.controllers.TransactionDialogController


    public static FinancialAccountsList selectListOfFinancialAccountOverviews(Long id) throws ServerException {
        ArrayList<FinancialAccount> financialAccounts = new ArrayList<>();
        String select = "SELECT f." + FINANCIAL_ACCOUNT_ID
                + ", f." + FINANCIAL_ACCOUNT_TITLE
                + ", f." + FINANCIAL_ACCOUNT_DESCRIPTION
                + ", COALESCE(SUM(t." + TRANSACTION_AMOUNT + "),0) AS " + FINANCIAL_ACCOUNT_BALANCE
                + " FROM " + FINANCIAL_ACCOUNT_TABLE + " f"
                + " LEFT JOIN " + TRANSACTION_TABLE + " t"
                + " ON t." + TRANSACTION_FINANCIAL_ACCOUNT_ID + " = f." + FINANCIAL_ACCOUNT_ID
                + " WHERE f." + FINANCIAL_ACCOUNT_OWNER_ID + " = ?"
                + " GROUP BY f." + FINANCIAL_ACCOUNT_ID;
        try (Connection conn = getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(select)) {
            stmt.setLong(1, id);
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    financialAccounts.add(new FinancialAccount(rs.getLong(FINANCIAL_ACCOUNT_ID),
                            rs.getString(FINANCIAL_ACCOUNT_TITLE),
                            rs.getString(FINANCIAL_ACCOUNT_DESCRIPTION),
                            rs.getBigDecimal(FINANCIAL_ACCOUNT_BALANCE),
                            null,
                            null,
                            null,
                            null,
                            null));
                    //TODO for later: Expand for Collaborators
                }
                return new FinancialAccountsList(financialAccounts);
            }
        } catch (SQLException e) {
            throw new ServerException(500, "Could not select financial account overview", e);
        }
    }

    public static FinancialAccountsList selectListOfFinancialAccountOverviews(Long id) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        ArrayList<FinancialAccount> financialAccounts = new ArrayList<>();
        String select = "SELECT f." + FINANCIAL_ACCOUNT_ID
                + ", f." + FINANCIAL_ACCOUNT_TITLE
                + ", f." + FINANCIAL_ACCOUNT_DESCRIPTION
                + ", COALESCE(SUM(t." + TRANSACTION_AMOUNT + "),0) AS " + FINANCIAL_ACCOUNT_BALANCE
                + " FROM " + FINANCIAL_ACCOUNT_TABLE + " f"
                + " LEFT JOIN " + TRANSACTION_TABLE + " t"
                + " ON t." + TRANSACTION_FINANCIAL_ACCOUNT_ID + " = f." + FINANCIAL_ACCOUNT_ID
                + " WHERE f." + FINANCIAL_ACCOUNT_OWNER_ID + " = ?"
                + " GROUP BY f." + FINANCIAL_ACCOUNT_ID;
        try {
            conn = DriverManager.getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
            pstmt = conn.prepareStatement(select);
            pstmt.setLong(1, id);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                financialAccounts.add(new FinancialAccount(rs.getLong(FINANCIAL_ACCOUNT_ID),
                        rs.getString(FINANCIAL_ACCOUNT_TITLE),
                        rs.getString(FINANCIAL_ACCOUNT_DESCRIPTION),
                        rs.getBigDecimal(FINANCIAL_ACCOUNT_BALANCE),
                        null,
                        null,
                        null,
                        null,
                        null));
                //TODO for later: Expand for Collaborators
            }
            return new FinancialAccountsList(financialAccounts);
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                throw e;
            }
        }
    }

Try With Resources try(ResultSet rs=stmt.executeQuery()) in method public selectListOfFinancialAccountOverviews(id Long) : FinancialAccountsList from class at.nicoleperak.server.Database


    public static FinancialAccount selectFullFinancialAccount(Long financialAccountId) throws ServerException {
        String select = "SELECT f." + FINANCIAL_ACCOUNT_TITLE
                + ", f." + FINANCIAL_ACCOUNT_DESCRIPTION
                + ", f." + FINANCIAL_ACCOUNT_OWNER_ID
                + ", COALESCE(SUM(t." + TRANSACTION_AMOUNT + "),0) AS " + FINANCIAL_ACCOUNT_BALANCE
                + ", u." + USER_NAME + " AS owner_username"
                + ", u." + USER_EMAIL + " AS owner_email"
                + " FROM " + FINANCIAL_ACCOUNT_TABLE + " f"
                + " INNER JOIN " + USER_TABLE + " u ON"
                + " u." + USER_ID + " = f." + FINANCIAL_ACCOUNT_OWNER_ID
                + " LEFT JOIN " + TRANSACTION_TABLE + " t ON"
                + " t." + TRANSACTION_FINANCIAL_ACCOUNT_ID + " = f." + FINANCIAL_ACCOUNT_ID
                + " WHERE f." + FINANCIAL_ACCOUNT_ID + " = ?"
                + " GROUP BY f." + FINANCIAL_ACCOUNT_ID + ", u." + USER_NAME + ", u." + USER_EMAIL;
        try (Connection conn = getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(select)) {
            stmt.setLong(1, financialAccountId);
            try (ResultSet rs = stmt.executeQuery()) {
                FinancialAccount financialAccount = new FinancialAccount();
                if (rs.next()) {
                    financialAccount.setId(financialAccountId);
                    financialAccount.setTitle(rs.getString(FINANCIAL_ACCOUNT_TITLE));
                    financialAccount.setDescription(rs.getString(FINANCIAL_ACCOUNT_DESCRIPTION));
                    financialAccount.setBalance(rs.getBigDecimal(FINANCIAL_ACCOUNT_BALANCE));
                    User owner = new User(rs.getLong(FINANCIAL_ACCOUNT_OWNER_ID),
                            rs.getString("owner_username"),
                            rs.getString("owner_email"),
                            null);
                    financialAccount.setOwner(owner);
                    financialAccount.setTransactions(selectListOfTransactions(financialAccountId));
                    //TODO for later: Expand for Collaborators, Financial Goals, Recurring TransactionOrders
                    return financialAccount;
                } else {
                    throw new ServerException(404, "Financial account with id " + financialAccountId + " does not exist");
                }
            }
        } catch (SQLException e) {
            throw new ServerException(500, "Could not select financial account details", e);
        }
    }

    public static FinancialAccount selectFullFinancialAccount(Long financialAccountId) throws ServerException, SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String select = "SELECT f." + FINANCIAL_ACCOUNT_TITLE
                + ", f." + FINANCIAL_ACCOUNT_DESCRIPTION
                + ", f." + FINANCIAL_ACCOUNT_OWNER_ID
                + ", COALESCE(SUM(t." + TRANSACTION_AMOUNT +"),0) AS " + FINANCIAL_ACCOUNT_BALANCE
                + ", u." + USER_NAME + " AS owner_username"
                + ", u." + USER_EMAIL + " AS owner_email"
                + " FROM " + FINANCIAL_ACCOUNT_TABLE + " f"
                + " INNER JOIN " + USER_TABLE + " u ON"
                + " u." + USER_ID + " = f." + FINANCIAL_ACCOUNT_OWNER_ID
                + " LEFT JOIN " + TRANSACTION_TABLE + " t ON"
                + " t." + TRANSACTION_FINANCIAL_ACCOUNT_ID + " = f." + FINANCIAL_ACCOUNT_ID
                + " WHERE f." + FINANCIAL_ACCOUNT_ID + " = ?"
                + " GROUP BY f." + FINANCIAL_ACCOUNT_ID + ", u." + USER_NAME + ", u." + USER_EMAIL;
        try {
            conn = DriverManager.getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
            pstmt = conn.prepareStatement(select);
            pstmt.setLong(1, financialAccountId);
            rs = pstmt.executeQuery();
            FinancialAccount financialAccount = new FinancialAccount();
            if (rs.next()) {
                financialAccount.setId(financialAccountId);
                financialAccount.setTitle(rs.getString(FINANCIAL_ACCOUNT_TITLE));
                financialAccount.setDescription(rs.getString(FINANCIAL_ACCOUNT_DESCRIPTION));
                financialAccount.setBalance(rs.getBigDecimal(FINANCIAL_ACCOUNT_BALANCE));
                User owner = new User(rs.getLong(FINANCIAL_ACCOUNT_OWNER_ID),
                        rs.getString("owner_username"),
                        rs.getString("owner_email"),
                        null);
                financialAccount.setOwner(owner);
                financialAccount.setTransactions(selectListOfTransactions(financialAccountId));
                //TODO for later: Expand for Collaborators, Financial Goals, Recurring TransactionOrders
                return financialAccount;
            } else {
                throw new ServerException(404, "Financial account with id " + financialAccountId + " does not exist");
            }
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                throw e;
            }
        }
    }

Try With Resources try(ResultSet rs=stmt.executeQuery()) in method public selectFullFinancialAccount(financialAccountId Long) : FinancialAccount from class at.nicoleperak.server.Database


    private static List<Transaction> selectListOfTransactions(Long financialAccountId) throws ServerException {
        String select = "SELECT t." + TRANSACTION_ID + " AS transaction_id, "
                + TRANSACTION_DESCRIPTION + ", " + TRANSACTION_AMOUNT + ", "
                + TRANSACTION_DATE + ", " + TRANSACTION_PARTNER + ", "
                + TRANSACTION_NOTE + ", " + TRANSACTION_ADDED_AUTOMATICALLY
                + ", t." + TRANSACTION_CATEGORY_ID
                + ", c." + CATEGORY_TITLE + " AS category_title"
                + ", c." + CATEGORY_TYPE
                + " FROM " + TRANSACTION_TABLE + " t"
                + " INNER JOIN " + CATEGORY_TABLE + " c ON"
                + " c." + CATEGORY_ID + " = t." + TRANSACTION_CATEGORY_ID
                + " WHERE t." + TRANSACTION_FINANCIAL_ACCOUNT_ID + " = ?"
                + " ORDER BY " + TRANSACTION_DATE + " DESC"
                + ", t. " + TRANSACTION_ID + " DESC";
        try (Connection conn = getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(select)) {
            stmt.setLong(1, financialAccountId);
            try (ResultSet rs = stmt.executeQuery()) {
                List<Transaction> transactionList = new ArrayList<>();
                while (rs.next()) {
                    transactionList.add(new Transaction(rs.getLong("transaction_id"),
                            rs.getString(TRANSACTION_DESCRIPTION),
                            rs.getBigDecimal(TRANSACTION_AMOUNT),
                            rs.getDate(TRANSACTION_DATE).toLocalDate(),
                            new Category(rs.getLong(TRANSACTION_CATEGORY_ID),
                                    rs.getString("category_title"),
                                    CategoryType.values()[rs.getShort(CATEGORY_TYPE)]),
                            rs.getString(TRANSACTION_PARTNER),
                            rs.getString(TRANSACTION_NOTE),
                            rs.getBoolean(TRANSACTION_ADDED_AUTOMATICALLY)));
                }
                return transactionList;
            }
        } catch (SQLException e) {
            throw new ServerException(500, "Could not select list of transactions", e);
        }
    }

    private static List<Transaction> selectListOfTransactions(Long financialAccountId) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String select = "SELECT t." + TRANSACTION_ID + " AS transaction_id, "
                + TRANSACTION_DESCRIPTION + ", "
                + TRANSACTION_AMOUNT + ", "
                + TRANSACTION_DATE + ", "
                + TRANSACTION_PARTNER + ", "
                + TRANSACTION_NOTE + ", "
                + TRANSACTION_ADDED_AUTOMATICALLY
                + ", t." + TRANSACTION_CATEGORY_ID
                + ", c." + CATEGORY_TITLE + " AS category_title"
                + ", c." + CATEGORY_TYPE
                + " FROM " + TRANSACTION_TABLE + " t"
                + " INNER JOIN " + CATEGORY_TABLE + " c ON"
                + " c." + CATEGORY_ID + " = t." + TRANSACTION_CATEGORY_ID
                + " WHERE t." + TRANSACTION_FINANCIAL_ACCOUNT_ID + " = ?"
                + " ORDER BY " + TRANSACTION_DATE + " DESC"
                + ", t. " + TRANSACTION_ID + " DESC";
        try {
            conn = DriverManager.getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
            pstmt = conn.prepareStatement(select);
            pstmt.setLong(1, financialAccountId);
            rs = pstmt.executeQuery();
            List<Transaction> transactionList = new ArrayList<>();
            while (rs.next()) {
                transactionList.add(new Transaction(rs.getLong("transaction_id"),
                        rs.getString(TRANSACTION_DESCRIPTION),
                        rs.getBigDecimal(TRANSACTION_AMOUNT),
                        rs.getDate(TRANSACTION_DATE).toLocalDate(),
                        new Category(rs.getLong(TRANSACTION_CATEGORY_ID),
                                rs.getString("category_title"),
                                CategoryType.values()[rs.getShort(CATEGORY_TYPE)]),
                        rs.getString(TRANSACTION_PARTNER),
                        rs.getString(TRANSACTION_NOTE),
                        rs.getBoolean(TRANSACTION_ADDED_AUTOMATICALLY)));
            }
            return transactionList;
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                throw e;
            }
        }
    }

Try With Resources try(ResultSet rs=stmt.executeQuery()) in method private selectListOfTransactions(financialAccountId Long) : List<Transaction> from class at.nicoleperak.server.Database


    public static List<Long> selectOwnerAndCollaboratorsIdsOfFinancialAccount(Long financialAccountId) throws ServerException {
        String select = "SELECT " + FINANCIAL_ACCOUNT_OWNER_ID + " FROM " + FINANCIAL_ACCOUNT_TABLE
                + " WHERE " + FINANCIAL_ACCOUNT_ID + " = ?";
        try (Connection conn = getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(select)) {
            stmt.setLong(1, financialAccountId);
            try (ResultSet rs = stmt.executeQuery()) {
                List<Long> userIds = new ArrayList<>();
                while (rs.next()) {
                    userIds.add(rs.getLong(FINANCIAL_ACCOUNT_OWNER_ID));
                    //TODO for later: Expand for Collaborators
                }
                return userIds;
            }
        } catch (SQLException e) {
            throw new ServerException(500, "Could not select user ids of financial account", e);
        }
    }

    public static List<Long> selectOwnerAndCollaboratorsIdsOfFinancialAccount(Long financialAccountId) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String select = "SELECT " + FINANCIAL_ACCOUNT_OWNER_ID + " FROM " + FINANCIAL_ACCOUNT_TABLE
                + " WHERE " + FINANCIAL_ACCOUNT_ID + " = ?";
        try {
            conn = DriverManager.getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
            pstmt = conn.prepareStatement(select);
            pstmt.setLong(1, financialAccountId);
            rs = pstmt.executeQuery();
            List<Long> userIds = new ArrayList<>();
            while (rs.next()) {
                userIds.add(rs.getLong(FINANCIAL_ACCOUNT_OWNER_ID));
                //TODO for later: Expand for Collaborators
            }
            return userIds;
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                throw e;
            }
        }
    }

Try With Resources try(ResultSet rs=stmt.executeQuery()) in method public selectOwnerAndCollaboratorsIdsOfFinancialAccount(financialAccountId Long) : List<Long> from class at.nicoleperak.server.Database


    public static CategoryList selectCategoryList(CategoryType categoryType) throws ServerException {
        ArrayList<Category> categories = new ArrayList<>();
        String select = "SELECT * FROM " + CATEGORY_TABLE
                + " WHERE " + CATEGORY_TYPE + " = ?";
        try (Connection conn = getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(select)) {
            stmt.setInt(1, categoryType.ordinal());
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    categories.add(
                            new Category(rs.getLong(CATEGORY_ID),
                                    rs.getString(CATEGORY_TITLE),
                                    CategoryType.values()[rs.getShort(CATEGORY_TYPE)]));
                }
                return new CategoryList(categories);
            }
        } catch (SQLException e) {
            throw new ServerException(500, "Could not select category list", e);
        }
    }

    public static CategoryList selectCategoryList(CategoryType categoryType) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        ArrayList<Category> categories = new ArrayList<>();
        String select = "SELECT * FROM " + CATEGORY_TABLE
                + " WHERE " + CATEGORY_TYPE + " = ?";
        try {
            conn = DriverManager.getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
            pstmt = conn.prepareStatement(select);
            pstmt.setInt(1, categoryType.ordinal());
            rs = pstmt.executeQuery();
            while (rs.next()) {
                categories.add(
                        new Category(rs.getLong(CATEGORY_ID),
                                rs.getString(CATEGORY_TITLE),
                                CategoryType.values()[rs.getShort(CATEGORY_TYPE)]));
            }
            return new CategoryList(categories);
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                throw e;
            }
        }
    }

Try With Resources try(ResultSet rs=stmt.executeQuery()) in method public selectCategoryList(categoryType CategoryType) : CategoryList from class at.nicoleperak.server.Database


    public static CategoryList selectCategoryList() throws ServerException {
        ArrayList<Category> categories = new ArrayList<>();
        String select = "SELECT * FROM " + CATEGORY_TABLE;
        try (Connection conn = getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(select)) {
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    categories.add(
                            new Category(rs.getLong(CATEGORY_ID),
                                    rs.getString(CATEGORY_TITLE),
                                    CategoryType.values()[rs.getShort(CATEGORY_TYPE)]));
                }
                return new CategoryList(categories);
            }
        } catch (SQLException e) {
            throw new ServerException(500, "Could not select category list", e);
        }
    }

    public static CategoryList selectCategoryList() throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        ArrayList<Category> categories = new ArrayList<>();
        String select = "SELECT * FROM " + CATEGORY_TABLE;
        try {
            conn = DriverManager.getConnection(CONNECTION, DB_USERNAME, DB_PASSWORD);
            pstmt = conn.prepareStatement(select);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                categories.add(
                        new Category(rs.getLong(CATEGORY_ID),
                                rs.getString(CATEGORY_TITLE),
                                CategoryType.values()[rs.getShort(CATEGORY_TYPE)]));
            }
            return new CategoryList(categories);
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                throw e;
            }
        }
    }

Try With Resources try(ResultSet rs=stmt.executeQuery()) in method public selectCategoryList() : CategoryList from class at.nicoleperak.server.Database


    @Override
    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext,
                                    final URI configLocation) {

        final LoggerContext lc = ContextAnchor.THREAD_CONTEXT.get();
        if (lc != null) {
            return lc;
        }

        String loggingContextName = null;

        try (final JndiManager jndiManager = JndiManager.getDefaultManager()) {
            loggingContextName = jndiManager.lookup(Constants.JNDI_CONTEXT_NAME);
        } catch (final NamingException ne) {
            LOGGER.error("Unable to lookup {}", Constants.JNDI_CONTEXT_NAME, ne);
        }

        return loggingContextName == null ? CONTEXT : locateContext(loggingContextName, null, configLocation);
    }

    @Override
    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext,
                                    final URI configLocation) {

        final LoggerContext lc = ContextAnchor.THREAD_CONTEXT.get();
        if (lc != null) {
            return lc;
        }

        String loggingContextName = null;

        final JndiManager jndiManager = JndiManager.getDefaultManager();
        try {
            loggingContextName = jndiManager.lookup(Constants.JNDI_CONTEXT_NAME);
        } catch (final NamingException ne) {
            LOGGER.error("Unable to lookup {}", Constants.JNDI_CONTEXT_NAME, ne);
        } finally {
            jndiManager.close();
        }

        return loggingContextName == null ? CONTEXT : locateContext(loggingContextName, null, configLocation);
    }

Try With Resources try(final JndiManager jndiManager=JndiManager.getDefaultManager()) in method public getContext(fqcn String, loader ClassLoader, currentContext boolean, configLocation URI) : LoggerContext from class org.apache.logging.log4j.core.selector.JndiContextSelector


    @Override
    public void send(final Layout<?> layout, final LogEvent event) throws IOException {
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        urlConnection.setAllowUserInteraction(false);
        urlConnection.setDoOutput(true);
        urlConnection.setDoInput(true);
        urlConnection.setRequestMethod(method);
        if (connectTimeoutMillis > 0) urlConnection.setConnectTimeout(connectTimeoutMillis);
        if (readTimeoutMillis > 0) urlConnection.setReadTimeout(readTimeoutMillis);
        if (layout.getContentType() != null) urlConnection.setRequestProperty("Content-Type", layout.getContentType());
        for (Property header : headers) {
            urlConnection.setRequestProperty(
                header.getName(),
                header.isValueNeedsLookup() ? getConfiguration().getStrSubstitutor().replace(event, header.getValue()) : header.getValue());
        }
        if (sslConfiguration != null) {
            ((HttpsURLConnection)urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
        }
        if (isHttps && !verifyHostname) {
            ((HttpsURLConnection)urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
        }

        byte[] msg = layout.toByteArray(event);
        urlConnection.setFixedLengthStreamingMode(msg.length);
        urlConnection.connect();
        try (OutputStream os = urlConnection.getOutputStream()) {
            os.write(msg);
        }

        byte[] buffer = new byte[1024];
        try (InputStream is = urlConnection.getInputStream()) {
            while (IOUtils.EOF != is.read(buffer));
        } catch (IOException e) {
            StringBuilder errorMessage = new StringBuilder();
            try (InputStream es = urlConnection.getErrorStream()) {
                errorMessage.append(urlConnection.getResponseCode());
                if (urlConnection.getResponseMessage() != null) {
                    errorMessage.append(' ').append(urlConnection.getResponseMessage());
                }
                if (es != null) {
                    errorMessage.append(" - ");
                    int n;
                    while (IOUtils.EOF != (n = es.read(buffer))) {
                        errorMessage.append(new String(buffer, 0, n, CHARSET));
                    }
                }
            }
            if (urlConnection.getResponseCode() > -1)
                throw new IOException(errorMessage.toString());
            else
                throw e;
        }
    }

    @Override
    public void send(final Layout<?> layout, final LogEvent event) throws IOException {
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        urlConnection.setAllowUserInteraction(false);
        urlConnection.setDoOutput(true);
        urlConnection.setDoInput(true);
        urlConnection.setRequestMethod(method);
        if (connectTimeoutMillis > 0) urlConnection.setConnectTimeout(connectTimeoutMillis);
        if (readTimeoutMillis > 0) urlConnection.setReadTimeout(readTimeoutMillis);
        if (layout.getContentType() != null) urlConnection.setRequestProperty("Content-Type", layout.getContentType());
        for (Property header : headers) {
            urlConnection.setRequestProperty(
                header.getName(),
                header.isValueNeedsLookup() ? getConfiguration().getStrSubstitutor().replace(event, header.getValue()) : header.getValue());
        }
        if (sslConfiguration != null) {
            ((HttpsURLConnection)urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
        }
        if (isHttps && !verifyHostname) {
            ((HttpsURLConnection)urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
        }

        byte[] msg = layout.toByteArray(event);
        urlConnection.setFixedLengthStreamingMode(msg.length);
        urlConnection.connect();
        try (OutputStream os = urlConnection.getOutputStream()) {
            os.write(msg);
        }

        byte[] buffer = new byte[1024];
        InputStream is = null;
        try {
            is = urlConnection.getInputStream();
            while (IOUtils.EOF != is.read(buffer));
        } catch (IOException e) {
            StringBuilder errorMessage = new StringBuilder();
            try (InputStream es = urlConnection.getErrorStream()) {
                errorMessage.append(urlConnection.getResponseCode());
                if (urlConnection.getResponseMessage() != null) {
                    errorMessage.append(' ').append(urlConnection.getResponseMessage());
                }
                if (es != null) {
                    errorMessage.append(" - ");
                    int n;
                    while (IOUtils.EOF != (n = es.read(buffer))) {
                        errorMessage.append(new String(buffer, 0, n, CHARSET));
                    }
                }
            }
            if (urlConnection.getResponseCode() > -1)
                throw new IOException(errorMessage.toString());
            else
                throw e;
        } finally {
            if (is != null) is.close();
        }
    }

Try With Resources try(InputStream is=urlConnection.getInputStream()) in method public send(layout Layout<?>, event LogEvent) : void from class org.apache.logging.log4j.core.appender.HttpURLConnectionManager


    @Test
    public void testDataSourceConfig() throws Exception {
        try (final Connection connection = jdbcRule.getConnectionSource().getConnection()) {
            final Error exception = new Error("Final error massage is fatal!");
            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            final PrintWriter writer = new PrintWriter(outputStream);
            exception.printStackTrace(writer);
            writer.close();
            final String stackTrace = outputStream.toString();

            final long millis = System.currentTimeMillis();

            final Logger logger = LogManager.getLogger(this.getClass().getName() + ".testDataSourceConfig");
            logger.trace("Data source logged message 01.");
            logger.fatal("Error from data source 02.", exception);

            final Statement statement = connection.createStatement();
            final ResultSet resultSet = statement.executeQuery("SELECT * FROM dsLogEntry ORDER BY id");

            assertTrue("There should be at least one row.", resultSet.next());

            final long date = resultSet.getTimestamp("eventDate").getTime();
            assertTrue("The date should be later than pre-logging (1).", date >= millis);
            assertTrue("The date should be earlier than now (1).", date <= System.currentTimeMillis());
            assertEquals("The literal column is not correct (1).", "Literal Value of Data Source",
                resultSet.getString("literalColumn"));
            assertEquals("The level column is not correct (1).", "FATAL", resultSet.getNString("level"));
            assertEquals("The logger column is not correct (1).", logger.getName(), resultSet.getNString("logger"));
            assertEquals("The message column is not correct (1).", "Error from data source 02.",
                resultSet.getString("message"));
            assertEquals("The exception column is not correct (1).", stackTrace,
                IOUtils.readStringAndClose(resultSet.getNClob("exception").getCharacterStream(), -1));

            assertFalse("There should not be two rows.", resultSet.next());
        }
    }

    @Test
    public void testDataSourceConfig() throws Exception {
        final DataSource dataSource = mock(DataSource.class);
        given(dataSource.getConnection()).willAnswer(new Answer<Connection>() {
            @Override
            public Connection answer(final InvocationOnMock invocation) throws Throwable {
                return newConnection();
            }
        });

        MockContextFactory.setAsInitial();

        final InitialContext context = new InitialContext();
        context.createSubcontext("java:");
        context.createSubcontext("java:/comp");
        context.createSubcontext("java:/comp/env");
        context.createSubcontext("java:/comp/env/jdbc");

        context.bind("java:/comp/env/jdbc/TestDataSourceAppender", dataSource);

        try {
            this.setUp("dsLogEntry", "log4j2-data-source.xml");

            final Error exception = new Error("Final error massage is fatal!");
            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            final PrintWriter writer = new PrintWriter(outputStream);
            exception.printStackTrace(writer);
            writer.close();
            final String stackTrace = outputStream.toString();

            final long millis = System.currentTimeMillis();

            final Logger logger = LogManager.getLogger(this.getClass().getName() + ".testDataSourceConfig");
            logger.trace("Data source logged message 01.");
            logger.fatal("Error from data source 02.", exception);

            final Statement statement = this.connection.createStatement();
            final ResultSet resultSet = statement.executeQuery("SELECT * FROM dsLogEntry ORDER BY id");

            assertTrue("There should be at least one row.", resultSet.next());

            final long date = resultSet.getTimestamp("eventDate").getTime();
            assertTrue("The date should be later than pre-logging (1).", date >= millis);
            assertTrue("The date should be earlier than now (1).", date <= System.currentTimeMillis());
            assertEquals("The literal column is not correct (1).", "Literal Value of Data Source",
                    resultSet.getString("literalColumn"));
            assertEquals("The level column is not correct (1).", "FATAL", resultSet.getNString("level"));
            assertEquals("The logger column is not correct (1).", logger.getName(), resultSet.getNString("logger"));
            assertEquals("The message column is not correct (1).", "Error from data source 02.",
                    resultSet.getString("message"));
            assertEquals("The exception column is not correct (1).", stackTrace,
                    IOUtils.readStringAndClose(resultSet.getNClob("exception").getCharacterStream(), -1));

            assertFalse("There should not be two rows.", resultSet.next());
        } finally {
            MockContextFactory.revertSetAsInitial();
        }
    }

Try With Resources try(final Connection connection=jdbcRule.getConnectionSource().getConnection()) in method public testDataSourceConfig() : void from class org.apache.logging.log4j.core.appender.db.jdbc.AbstractJdbcAppenderDataSourceTest


    @Test
    public void testWriteInternalNotConnected02() {
        given(connection.isClosed()).willReturn(true);

        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
            provider)) {

            manager.startup();
            manager.connectAndStart();
            then(provider).should().getConnection();

            expectedException.expect(AppenderLoggingException.class);
            manager.writeInternal(mock(LogEvent.class));
        }
    }

    @Test
    public void testWriteInternalNotConnected02() {
        final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0, this.provider);

        try {
            replay(this.provider, this.connection);

            manager.startup();

            verify(this.provider, this.connection);
            reset(this.provider, this.connection);
            expect(this.provider.getConnection()).andReturn(this.connection);
            replay(this.provider, this.connection);

            manager.connectAndStart();

            verify(this.provider, this.connection);
            reset(this.provider, this.connection);

            final LogEvent event = createStrictMock(LogEvent.class);
            expect(this.connection.isClosed()).andReturn(true);
            replay(this.provider, this.connection, event);

            try {
                manager.writeInternal(event);
                fail("Expected AppenderLoggingException.");
            } catch (final AppenderLoggingException ignore) {
                /* */
            }
        } finally {
            try {
                manager.close();
            } catch (final Throwable ignore) {
                /* */
            }
        }
    }

Try With Resources try(final NoSqlDatabaseManager<?> manager=NoSqlDatabaseManager.getNoSqlDatabaseManager("name",0,provider)) in method public testWriteInternalNotConnected02() : void from class org.apache.logging.log4j.nosql.appender.NoSqlDatabaseManagerTest


    @Test
    public void testWriteInternal01() {
        given(connection.isClosed()).willReturn(false);
        given(message.getFormattedMessage()).willReturn("My formatted message 01.");

        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
            provider)) {

            manager.startup();
            manager.connectAndStart();
            then(provider).should().getConnection();

            final LogEvent event = Log4jLogEvent.newBuilder()
                .setLevel(Level.WARN)
                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal01")
                .setMessage(message)
                .setSource(new StackTraceElement("com.foo.Bar", "testMethod01", "Bar.java", 15))
                .setThreadId(1L)
                .setThreadName("MyThread-A")
                .setThreadPriority(1)
                .setTimeMillis(1234567890123L)
                .build();

            manager.writeInternal(event);
            then(connection).should().insertObject(captor.capture());

            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
            assertNotNull("The inserted value should not be null.", inserted);
            final Map<String, Object> object = inserted.unwrap();
            assertNotNull("The unwrapped object should not be null.", object);

            assertEquals("The level is not correct.", Level.WARN, object.get("level"));
            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal01",
                object.get("loggerName"));
            assertEquals("The message is not correct.", "My formatted message 01.", object.get("message"));
            assertEquals("The thread is not correct.", "MyThread-A", object.get("threadName"));
            assertEquals("The millis is not correct.", 1234567890123L, object.get("millis"));
            assertEquals("The date is not correct.", 1234567890123L, ((Date) object.get("date")).getTime());

            assertTrue("The source should be a map.", object.get("source") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> source = (Map<String, Object>) object.get("source");
            assertEquals("The class is not correct.", "com.foo.Bar", source.get("className"));
            assertEquals("The method is not correct.", "testMethod01", source.get("methodName"));
            assertEquals("The file name is not correct.", "Bar.java", source.get("fileName"));
            assertEquals("The line number is not correct.", 15, source.get("lineNumber"));

            assertNull("The marker should be null.", object.get("marker"));

            assertNull("The thrown should be null.", object.get("thrown"));

            assertTrue("The context map should be empty.", ((Map) object.get("contextMap")).isEmpty());

            assertTrue("The context stack should be null.", ((Collection) object.get("contextStack")).isEmpty());

        }
    }

    @Test
    public void testWriteInternal01() {
        final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0, this.provider);

        try {
            replay(this.provider, this.connection);

            manager.startup();

            verify(this.provider, this.connection);
            reset(this.provider, this.connection);
            expect(this.provider.getConnection()).andReturn(this.connection);
            replay(this.provider, this.connection);

            manager.connectAndStart();

            verify(this.provider, this.connection);
            reset(this.provider, this.connection);

            final Capture<NoSqlObject<Map<String, Object>>> capture = EasyMock.newCapture();

            final LogEvent event = createStrictMock(LogEvent.class);
            final Message message = createStrictMock(Message.class);

            expect(this.connection.isClosed()).andReturn(false);
            expect(this.connection.createObject()).andAnswer(new IAnswer<DefaultNoSqlObject>() {
                @Override
                public DefaultNoSqlObject answer() throws Throwable {
                    return new DefaultNoSqlObject();
                }
            }).atLeastOnce();
            expect(event.getLevel()).andReturn(Level.WARN);
            expect(event.getLoggerName()).andReturn("com.foo.NoSQLDbTest.testWriteInternal01");
            expect(event.getMessage()).andReturn(message).times(2);
            expect(message.getFormattedMessage()).andReturn("My formatted message 01.");
            expect(event.getSource()).andReturn(new StackTraceElement("com.foo.Bar", "testMethod01", "Bar.java", 15));
            expect(event.getMarker()).andReturn(null);
            expect(event.getThreadId()).andReturn(1L);
            expect(event.getThreadName()).andReturn("MyThread-A");
            expect(event.getThreadPriority()).andReturn(1);
            expect(event.getTimeMillis()).andReturn(1234567890123L).times(2);
            expect(event.getThrown()).andReturn(null);
            expect(event.getContextMap()).andReturn(null);
            expect(event.getContextStack()).andReturn(null);
            this.connection.insertObject(capture(capture));
            expectLastCall();
            replay(this.provider, this.connection, event, message);

            manager.writeInternal(event);

            final NoSqlObject<Map<String, Object>> inserted = capture.getValue();
            assertNotNull("The inserted value should not be null.", inserted);
            final Map<String, Object> object = inserted.unwrap();
            assertNotNull("The unwrapped object should not be null.", object);

            assertEquals("The level is not correct.", Level.WARN, object.get("level"));
            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal01",
                    object.get("loggerName"));
            assertEquals("The message is not correct.", "My formatted message 01.", object.get("message"));
            assertEquals("The thread is not correct.", "MyThread-A", object.get("threadName"));
            assertEquals("The millis is not correct.", 1234567890123L, object.get("millis"));
            assertEquals("The date is not correct.", 1234567890123L, ((Date) object.get("date")).getTime());

            assertTrue("The source should be a map.", object.get("source") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> source = (Map<String, Object>) object.get("source");
            assertEquals("The class is not correct.", "com.foo.Bar", source.get("className"));
            assertEquals("The method is not correct.", "testMethod01", source.get("methodName"));
            assertEquals("The file name is not correct.", "Bar.java", source.get("fileName"));
            assertEquals("The line number is not correct.", 15, source.get("lineNumber"));

            assertNull("The marker should be null.", object.get("marker"));

            assertNull("The thrown should be null.", object.get("thrown"));

            assertNull("The context map should be null.", object.get("contextMap"));

            assertNull("The context stack should be null.", object.get("contextStack"));

            verify(this.provider, this.connection, event, message);
        } finally {
            try {
                manager.close();
            } catch (final Throwable ignore) {
                /* */
            }
        }
    }

Try With Resources try(final NoSqlDatabaseManager<?> manager=NoSqlDatabaseManager.getNoSqlDatabaseManager("name",0,provider)) in method public testWriteInternal01() : void from class org.apache.logging.log4j.nosql.appender.NoSqlDatabaseManagerTest


    @Test
    public void testWriteInternal02() {
        given(connection.isClosed()).willReturn(false);
        given(message.getFormattedMessage()).willReturn("Another cool message 02.");

        try (final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0,
            provider)) {
            manager.startup();

            manager.connectAndStart();
            then(provider).should().getConnection();

            final RuntimeException exception = new RuntimeException("This is something cool!");
            final Map<String, String> context = new HashMap<>();
            context.put("hello", "world");
            context.put("user", "pass");

            ThreadContext.push("message1");
            ThreadContext.push("stack2");
            final ThreadContext.ContextStack stack = ThreadContext.getImmutableStack();
            ThreadContext.clearStack();

            final LogEvent event = Log4jLogEvent.newBuilder()
                .setLevel(Level.DEBUG)
                .setLoggerName("com.foo.NoSQLDbTest.testWriteInternal02")
                .setMessage(message)
                .setSource(new StackTraceElement("com.bar.Foo", "anotherMethod03", "Foo.java", 9))
                .setMarker(MarkerManager.getMarker("LoneMarker"))
                .setThreadId(1L)
                .setThreadName("AnotherThread-B")
                .setThreadPriority(1)
                .setTimeMillis(987654321564L)
                .setThrown(exception)
                .setContextMap(context)
                .setContextStack(stack)
                .build();

            manager.writeInternal(event);
            then(connection).should().insertObject(captor.capture());

            final NoSqlObject<Map<String, Object>> inserted = captor.getValue();
            assertNotNull("The inserted value should not be null.", inserted);
            final Map<String, Object> object = inserted.unwrap();
            assertNotNull("The unwrapped object should not be null.", object);

            assertEquals("The level is not correct.", Level.DEBUG, object.get("level"));
            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal02",
                object.get("loggerName"));
            assertEquals("The message is not correct.", "Another cool message 02.", object.get("message"));
            assertEquals("The thread is not correct.", "AnotherThread-B", object.get("threadName"));
            assertEquals("The millis is not correct.", 987654321564L, object.get("millis"));
            assertEquals("The date is not correct.", 987654321564L, ((Date) object.get("date")).getTime());

            assertTrue("The source should be a map.", object.get("source") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> source = (Map<String, Object>) object.get("source");
            assertEquals("The class is not correct.", "com.bar.Foo", source.get("className"));
            assertEquals("The method is not correct.", "anotherMethod03", source.get("methodName"));
            assertEquals("The file name is not correct.", "Foo.java", source.get("fileName"));
            assertEquals("The line number is not correct.", 9, source.get("lineNumber"));

            assertTrue("The marker should be a map.", object.get("marker") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> marker = (Map<String, Object>) object.get("marker");
            assertEquals("The marker name is not correct.", "LoneMarker", marker.get("name"));
            assertNull("The marker parent should be null.", marker.get("parent"));

            assertTrue("The thrown should be a map.", object.get("thrown") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> thrown = (Map<String, Object>) object.get("thrown");
            assertEquals("The thrown type is not correct.", "java.lang.RuntimeException", thrown.get("type"));
            assertEquals("The thrown message is not correct.", "This is something cool!", thrown.get("message"));
            assertTrue("The thrown stack trace should be a list.", thrown.get("stackTrace") instanceof List);
            @SuppressWarnings("unchecked")
            final List<Map<String, Object>> stackTrace = (List<Map<String, Object>>) thrown.get("stackTrace");
            assertEquals("The thrown stack trace length is not correct.", exception.getStackTrace().length,
                stackTrace.size());
            for (int i = 0; i < exception.getStackTrace().length; i++) {
                final StackTraceElement e1 = exception.getStackTrace()[i];
                final Map<String, Object> e2 = stackTrace.get(i);

                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
                    e2.get("methodName"));
                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
                    e2.get("lineNumber"));
            }
            assertNull("The thrown should have no cause.", thrown.get("cause"));

            assertTrue("The context map should be a map.", object.get("contextMap") instanceof Map);
            assertEquals("The context map is not correct.", context, object.get("contextMap"));

            assertTrue("The context stack should be list.", object.get("contextStack") instanceof List);
            assertEquals("The context stack is not correct.", stack.asList(), object.get("contextStack"));
        }
    }

    @Test
    public void testWriteInternal02() {
        final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager("name", 0, this.provider);

        try {
            replay(this.provider, this.connection);

            manager.startup();

            verify(this.provider, this.connection);
            reset(this.provider, this.connection);
            expect(this.provider.getConnection()).andReturn(this.connection);
            replay(this.provider, this.connection);

            manager.connectAndStart();

            verify(this.provider, this.connection);
            reset(this.provider, this.connection);

            final Capture<NoSqlObject<Map<String, Object>>> capture = EasyMock.newCapture();

            final RuntimeException exception = new RuntimeException("This is something cool!");
            final Map<String, String> context = new HashMap<>();
            context.put("hello", "world");
            context.put("user", "pass");

            final LogEvent event = createStrictMock(LogEvent.class);
            final Message message = createStrictMock(Message.class);
            ThreadContext.push("message1");
            ThreadContext.push("stack2");
            final ThreadContext.ContextStack stack = ThreadContext.getImmutableStack();
            ThreadContext.clearStack();

            expect(this.connection.isClosed()).andReturn(false);
            expect(this.connection.createObject()).andAnswer(new IAnswer<DefaultNoSqlObject>() {
                @Override
                public DefaultNoSqlObject answer() throws Throwable {
                    return new DefaultNoSqlObject();
                }
            }).atLeastOnce();
            expect(this.connection.createList(anyInt())).andAnswer(new IAnswer<DefaultNoSqlObject[]>() {
                @Override
                public DefaultNoSqlObject[] answer() throws Throwable {
                    return new DefaultNoSqlObject[(Integer) getCurrentArguments()[0]];
                }
            });
            expect(this.connection.createObject()).andAnswer(new IAnswer<DefaultNoSqlObject>() {
                @Override
                public DefaultNoSqlObject answer() throws Throwable {
                    return new DefaultNoSqlObject();
                }
            }).atLeastOnce();
            expect(event.getLevel()).andReturn(Level.DEBUG);
            expect(event.getLoggerName()).andReturn("com.foo.NoSQLDbTest.testWriteInternal02");
            expect(event.getMessage()).andReturn(message).times(2);
            expect(message.getFormattedMessage()).andReturn("Another cool message 02.");
            expect(event.getSource()).andReturn(new StackTraceElement("com.bar.Foo", "anotherMethod03", "Foo.java", 9));
            expect(event.getMarker()).andReturn(MarkerManager.getMarker("LoneMarker"));
            expect(event.getThreadId()).andReturn(1L);
            expect(event.getThreadName()).andReturn("AnotherThread-B");
            expect(event.getThreadPriority()).andReturn(1);
            expect(event.getTimeMillis()).andReturn(987654321564L).times(2);
            expect(event.getThrown()).andReturn(exception);
            expect(event.getContextMap()).andReturn(context);
            expect(event.getContextStack()).andReturn(stack);
            this.connection.insertObject(capture(capture));
            expectLastCall();
            replay(this.provider, this.connection, event, message);

            manager.writeInternal(event);

            final NoSqlObject<Map<String, Object>> inserted = capture.getValue();
            assertNotNull("The inserted value should not be null.", inserted);
            final Map<String, Object> object = inserted.unwrap();
            assertNotNull("The unwrapped object should not be null.", object);

            assertEquals("The level is not correct.", Level.DEBUG, object.get("level"));
            assertEquals("The logger is not correct.", "com.foo.NoSQLDbTest.testWriteInternal02",
                    object.get("loggerName"));
            assertEquals("The message is not correct.", "Another cool message 02.", object.get("message"));
            assertEquals("The thread is not correct.", "AnotherThread-B", object.get("threadName"));
            assertEquals("The millis is not correct.", 987654321564L, object.get("millis"));
            assertEquals("The date is not correct.", 987654321564L, ((Date) object.get("date")).getTime());

            assertTrue("The source should be a map.", object.get("source") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> source = (Map<String, Object>) object.get("source");
            assertEquals("The class is not correct.", "com.bar.Foo", source.get("className"));
            assertEquals("The method is not correct.", "anotherMethod03", source.get("methodName"));
            assertEquals("The file name is not correct.", "Foo.java", source.get("fileName"));
            assertEquals("The line number is not correct.", 9, source.get("lineNumber"));

            assertTrue("The marker should be a map.", object.get("marker") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> marker = (Map<String, Object>) object.get("marker");
            assertEquals("The marker name is not correct.", "LoneMarker", marker.get("name"));
            assertNull("The marker parent should be null.", marker.get("parent"));

            assertTrue("The thrown should be a map.", object.get("thrown") instanceof Map);
            @SuppressWarnings("unchecked")
            final Map<String, Object> thrown = (Map<String, Object>) object.get("thrown");
            assertEquals("The thrown type is not correct.", "java.lang.RuntimeException", thrown.get("type"));
            assertEquals("The thrown message is not correct.", "This is something cool!", thrown.get("message"));
            assertTrue("The thrown stack trace should be a list.", thrown.get("stackTrace") instanceof List);
            @SuppressWarnings("unchecked")
            final List<Map<String, Object>> stackTrace = (List<Map<String, Object>>) thrown.get("stackTrace");
            assertEquals("The thrown stack trace length is not correct.", exception.getStackTrace().length,
                    stackTrace.size());
            for (int i = 0; i < exception.getStackTrace().length; i++) {
                final StackTraceElement e1 = exception.getStackTrace()[i];
                final Map<String, Object> e2 = stackTrace.get(i);

                assertEquals("Element class name [" + i + "] is not correct.", e1.getClassName(), e2.get("className"));
                assertEquals("Element method name [" + i + "] is not correct.", e1.getMethodName(),
                        e2.get("methodName"));
                assertEquals("Element file name [" + i + "] is not correct.", e1.getFileName(), e2.get("fileName"));
                assertEquals("Element line number [" + i + "] is not correct.", e1.getLineNumber(),
                        e2.get("lineNumber"));
            }
            assertNull("The thrown should have no cause.", thrown.get("cause"));

            assertTrue("The context map should be a map.", object.get("contextMap") instanceof Map);
            assertEquals("The context map is not correct.", context, object.get("contextMap"));

            assertTrue("The context stack should be list.", object.get("contextStack") instanceof List);
            assertEquals("The context stack is not correct.", stack.asList(), object.get("contextStack"));

            verify(this.provider, this.connection, event, message);
        } finally {
            try {
                manager.close();
            } catch (final Throwable ignore) {
                /* */
            }
        }
    }

Try With Resources try(final NoSqlDatabaseManager<?> manager=NoSqlDatabaseManager.getNoSqlDatabaseManager("name",0,provider)) in method public testWriteInternal02() : void from class org.apache.logging.log4j.nosql.appender.NoSqlDatabaseManagerTest