W tym artykule opisuję nietypowy, lecz wcale nie rzadki przypadek, z którym może zmierzyć się każdy twórca aplikacji webowych. Port 8080 domyślnie wykorzystywany przez wiele aplikacji Spring Boot był zajęty przez nieznaną usługę systemową. Źródłem problemu okazało się dodatkowe oprogramowanie zainstalowane „przy okazji” razem z narzędziem do zarządzania partycjami dysku.
Na konkretnym przykładzie pokażę, jak krok po kroku zdiagnozować takie sytuacje za pomocą wbudowanych narzędzi systemowych i PowerShella.
Choć opis dotyczy aplikacji Spring Boot uruchamianej w środowisku Eclipse, to również programiści korzystający z innych języków i frameworków takich jak Node.js, .NET czy Python znajdą tu uniwersalne wskazówki, pomocne w rozwiązywaniu problemów z konfliktem portów.
Przypadek został przeanalizowany na systemie Windows z pełnymi uprawnieniami administratora. Opisywane metody nie były testowane w systemach Linux ani macOS, w których mogą występować inne narzędzia oraz odmienna procedura rozwiązywania podobnych problemów.
Objawy
Po uruchomieniu aplikacji Spring Boot pojawił się błąd:
APPLICATION FAILED TO START
Web server failed to start. Port 8080 was already in use.
To jasna wskazówka, że ktoś już korzysta z portu 8080. Wymagana była diagnoza, kto to robi i dlaczego.
Narzędzia diagnostyczne i komendy
Poniżej zestaw narzędzi systemowych i komend PowerShell/CMD użytych do analizy sytuacji.
1. Sprawdzenie, co nasłuchuje na porcie 8080
W terminalu wpisz następujące polecenie.
netstat -ano | findstr :8080
Ta komenda pozwala zidentyfikować, czy port jest aktualnie w użyciu i przez jaki proces (PID). W moim przypadku w konsoli wyświetliła się linia. Ostatnia wartość to identyfikator procesu.
TCP 0.0.0.0:8080 LISTENING 5184
2. Kto używa PID 5184?
Aby dowiedzieć się, jaki program odpowiada za dany PID, używamy komendy tasklist.
tasklist /FI "PID eq 5184"
Dla mojego przypadku wynik wskazywał na AgentService.exe, ale brak było dodatkowych informacji.
3. Identyfikacja lokalizacji procesu (z uprawnieniami administratora)
Wykonanie tej komendy pozwala sprawdzić dokładną ścieżkę do pliku wykonywalnego procesu.
Get-Process -Id 5184 | Select-Object Path
W wyniku została wyświetlona linia:
C:\Program Files\MiniTool ShadowMaker\AgentService.exe
4. Szczegóły usługi
Poniższe polecenie pozwala ustalić, czy proces działa jako usługa systemowa oraz jak się nazywa i jaki ma tryb uruchamiania.
Get-WmiObject Win32_Service | Where-Object { $_.ProcessId -eq 5184 } |
Select-Object Name, DisplayName, PathName, State, StartMode
Na ekranie Windows PowerShell wyświetliło się:
Name : MTAgentService
DisplayName : MTAgentService
PathName : "C:\Program F...\MiniTool ShadowMaker\AgentService.exe"
State : Running
StartMode : Auto
Ustalenia
Usługa MTAgentService, zainstalowana wraz z MiniTool ShadowMaker PW Edition, blokowała port 8080. Co ciekawe, narzędzie to było zainstalowane tego samego dnia co MiniTool Partition Wizard, najprawdopodobniej jako komponent dodatkowy.
Sprawdzenie daty instalacji aplikacji
Aby ustalić, które programy zostały zainstalowane danego dnia (np. 23 lutego 2025 roku), można wykorzystać rejestr systemu Windows. Informacje o zainstalowanych aplikacjach przechowywane są w kluczach rejestru, z których możemy odczytać m.in. nazwę aplikacji (DisplayName) oraz datę instalacji (InstallDate).
Poniższe polecenie PowerShell pozwala przeszukać rejestr systemowy i wyświetlić aplikacje zainstalowane danego dnia:
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" |
Where-Object { $_.InstallDate -eq "20250223" } |
Select-Object DisplayName, InstallDate
W systemach 64-bitowych programy 32-bitowe instalowane są w osobnym obszarze rejestru (Wow6432Node). Jeśli chcesz mieć pełny obraz (aplikacje 64- i 32-bitowe), skorzystaj z poniższego skryptu:
$uninstallKeys = @(
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
foreach ($key in $uninstallKeys) {
Get-ItemProperty $key |
Where-Object { $_.InstallDate -eq "20250223" } |
Select-Object DisplayName, InstallDate
}
📌 Wyjaśnienie:
$uninstallKeysto tablica zawierająca ścieżki do dwóch lokalizacji w rejestrze: dla aplikacji 64-bitowych i 32-bitowych.foreach– pętla, która iteruje po tych dwóch lokalizacjach i wykonuje dla każdej z nich filtrację oraz wybór danych.
W moim przypadku na ekranie wyświetliły się następujące aplikacje:
DisplayName InstallDate
----------- -----------
MiniTool Partition Wizard 12.9 DEMO 20250223
MiniTool ShadowMaker PW Edition 20250223
Rekomendacje
- Unikaj domyślnego portu 8080 w aplikacjach deweloperskich
Port 8080 to jeden z najczęściej wykorzystywanych portów przez aplikacje webowe i narzędzia firm trzecich (takie jak MiniTool ShadowMaker, IIS, serwery BI czy inne lokalne usługi). Jeśli tworzysz aplikację w Spring Boot, Node.js, React czy innym frameworku rozważ ustawienie alternatywnego portu, np. 8081, 5173, 3000 albo wybranego zgodnie z wewnętrznym standardem zespołu.
- Standaryzacja i dokumentacja portów
W projektach zespołowych warto ustalić stałe porty dla różnych środowisk (np. 8081 dla developmentu, 8082 dla testów), by uniknąć konfliktów i ułatwić automatyzację. Przydatne jest także dodanie do repozytorium pliku .env.example lub dokumentacji z opisem portów i zmiennych środowiskowych używanych przez aplikację. W przypadku Spring Boot można odczytywać takie zmienne w application.properties, np. przez ${SPRING_PORT:8080}.
Jeśli chcesz zagłębić się w temat używania plików .env w aplikacjach Spring Boot, sprawdź ten przystępny artykuł:
How to use .env files with Spring Boot – surly.dev
- Losowy wolny port w Spring Boot
Jeśli chcesz, aby Spring Boot dynamicznie dobrał wolny port, ustaw w application.properties:
server.port=0
Port zostanie wyświetlony w logu przy starcie aplikacji.
- Sprawdzenie aktywnych portów po każdej instalacji oprogramowania
Po instalacji nowego programu sprawdź, które porty są aktualnie nasłuchiwane. Możesz użyć polecenia:
Get-NetTCPConnection -State Listen |
Group-Object LocalPort |
Sort-Object Name
- Korzystaj z TCPView do szybkiej analizy portów
Graficzne narzędzie TCPView od Sysinternals to niezastąpione wsparcie w wykrywaniu konfliktów portów. Pozwala błyskawicznie zidentyfikować proces, usługę i lokalizację aplikacji nasłuchującej na danym porcie.

- Ostrożność przy instalacji oprogramowania narzędziowego
Instalując narzędzia typu „partition manager”, „backup software” czy „BI agent”, wybieraj tryb instalacji niestandardowej (custom), aby wykluczyć dodatkowe komponenty. Wielu producentów instaluje przy okazji własne usługi systemowe, które mogą działać w tle i blokować kluczowe porty.
Przypadek korporacyjny
Ten przypadek dotyczył stacji roboczej z pełnymi prawami administratora. W środowisku korporacyjnym sytuacja jest trudniejsza:
- Brak dostępu do zaawansowanych komend
- Brak uprawnień do zatrzymywania usług
- Konieczność zgłoszenia do helpdesku
W następnym wpisie zaproponuję podejście do tworzenia zgłoszenia serwisowego oraz przygotowania pakietu diagnostycznego do analizy problemów z portami, uruchamianiem aplikacji oraz konfliktem usług w firmowym systemie Windows.
Podsumowanie
To studium przypadku pokazuje, jak niepozorne narzędzie może skutecznie zablokować pracę nad aplikacją. Diagnoza i znajomość narzędzi systemowych (takich jak PowerShell, TCPView, netstat) są nieocenione w codziennej pracy deweloperskiej. Ten przypadek zostanie rozszerzony o scenariusz korporacyjny, by pomóc innym programistom i administratorom szybciej reagować na podobne problemy.
FAQ
Czy InstallDate zależy od języka i lokalizacji systemu?
Nie. Wartość InstallDate zapisywana w kluczach:
HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\
to liczba całkowita reprezentująca datę w formacie YYYYMMDD (czyli RRRRMMDD, np. 20250223 oznacza 23 lutego 2025). Jest to techniczna wartość typu DWORD, a nie tekstowa reprezentacja daty, więc nie podlega lokalizacji, ustawieniom regionalnym ani formatom wyświetlania.
Dlaczego PowerShell może błędnie wkleić polecenie?
Kiedy kopiujesz dłuższy blok kodu do konsoli PowerShell bezpośrednio z przeglądarki, upewnij się, że całość wkleiła się poprawnie. Zdarza się, że kolejność linii może się odwrócić lub złamać (szczególnie w pętli foreach), co prowadzi do błędów takich jak:
Select-Object DisplayName, InstallDate
>> Where-Object { $_.InstallDate -eq "20250223" } |
>> Get-ItemProperty ...
Rozwiązanie: Wklej cały blok kodu najpierw do edytora tekstu (np. Notepad++ lub VS Code), a dopiero potem do PowerShella. Alternatywnie użyj terminala PowerShell ISE lub Windows Terminal, które lepiej radzą sobie z wieloliniowym kodem.
Masz podobny przypadek? Podziel się w komentarzu lub napisz do mnie na LinkedIn.
