javax.management.InstanceNotFoundException: Catalina:type=Server
修改tomcat端口時卻仍是8080
沒有使用在idea tomcat中配置的端口的情況
查看堆棧錯誤原因
mvc跨服務器上傳時,需要配置多個服務器,因為對idea啟動服務器的流程不夠清晰,所以兩個tomcat server的configure中設置了同個tomcat 地址,引發了上面的三個同個根源的問題,之后是解決的思路與總結
- 直接復制粘貼相應的錯誤報告(javax.management.InstanceNotFoundException: Catalina:type=Server)到google和百度上查詢
-
出現的多為修改host和Connector port 后出現的無法匹配問題,為單個服務器的問題,而我單個服務器的配置時並無問題,也有查過兩個服務器與報錯兩者相關聯的報錯信息,但是可能因為問題的描述不對,導致無論stackflow還是其他論壇中相同的問題,答案卻並不符合,快速解決的路子不通了,只能自己翻看錯誤報告了
-
首先,錯誤報告中最吸引人的字樣是protocol中的 8080端口,因為idea的中無論 http port無論如何修改,到這里總是顯示有關8080 端口的信息。
這里嘗試過先啟動idea中設置的8080 端口的服務器,再啟動idea中設置為8089的同一個文件夾下的tomcat,服務器會開始部署,但到最后會出現javax.management.InstanceNotFoundException: Catalina:type=Server
而先開啟8089的tomcat,再開啟8080的,則會直接顯示8080端口被占用。
idea 的tomcat組件的作用:如同start.up一樣幫我們預處理,其中的http port 的設置作用是idea會先幫我檢查這個端口有沒有被使用,若有,則直接報錯端口占用(若不一致此時他並不會檢查你的tomcat的server.xml中有沒有啟動這個端口);若沒有則,設定部署的一些參數,然后尋找tomcat服務器文件的位置以啟動tomcat,啟動application server中設置的tomcat服務器地址中的catalina.bat,這也是出現javax.management.InstanceNotFoundException: Catalina:type=Server該錯誤的地方,最后打開默認地址。
- 很明顯,多次更改了idea中的配置,仍然出現的是8080端口,證明應該是啟動過程中引用的其它文件的問題(因為引用的是tomcat服務,所以自然而然地想到tomcat服務器的配置問題),向上翻找啟動順序。
- 看到了\bin\catalina.bat,可以讓我們很容易聯想到剛學tomcat時,最原始的啟動方式:startup.bat,他也是通過啟動catalina.bat來啟動tomcat服務器的配置的,從這我們可以看出idea的tomcat server配置相當於自己完成了startup.bat功能。
tomcat startup.bat
startup.bat詳解**
if "%OS%" == "Windows_NT" setlocal //判斷當前系統是否是window系統
rem --------------------------------------------------------------------------- //rem 是注釋(下同)
rem Start script for the CATALINA Server
rem
rem $Id: startup.bat 302918 2004-05-27 18:25:11Z yoavs $
rem ---------------------------------------------------------------------------
rem Guess CATALINA_HOME if not defined
set CURRENT_DIR=%cd% //設置當前目錄
if not "%CATALINA_HOME%" == "" gotogotHome //如果設置了CATALINA_HOME環境變量 ,就直接到下面的gotHome處
set CATALINA_HOME=%CURRENT_DIR% //如果沒有設置CATALINA_HOME,就設置CATALINA_HOME為當前目錄(其實這里她假設你進入tomcat的安裝目錄)
if exist "%CATALINA_HOME%\bin\catalina.bat" gotookHome//判斷一下catalina.bat是否找到了,找到了就直接到下面的gotHome處
cd .. //這里他是假設你開始已經進入到了tomcat的bin目錄,所以就退到上一級目錄
set CATALINA_HOME=%cd%//現在再設置CATALINA_HOME為tomcat的安裝目錄
cd %CURRENT_DIR% //這里是進入dos的當前目錄
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" gotookHome //再次判斷catalina.bat是否找到了,找到了就直接到下面的okHome處,沒有的話,就只能提示你啦!
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat //設置要執行的文件
rem Check that target executable exists
if exist "%EXECUTABLE%" gotookExec //再次判斷catalina.bat是否找到了,找到了就直接到下面的okExec處,沒有的話,就提示。
echo Cannot find %EXECUTABLE%
echo This file is needed to run this program
goto end
:okExec
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS= //這里是設置參數
:setArgs
if ""%1""=="""" gotodoneSetArgs //判斷參數是否加入完成
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 //將參數組成一行,接在后面
shift
gotosetArgs
:doneSetArgs
call "%EXECUTABLE%" start %CMD_LINE_ARGS% //執行catalina.bat,最好將這行改為:echo "%EXECUTABLE%" start %CMD_LINE_ARGS% 以便閱讀、理解本文件的作用
:end
Catalina.bat
- 可以看出startup.bat 主要是進行一些環境的判斷,然后啟動catalina.bat,Catalina.bat是tomcat所有腳本中最重要的腳本,完成幾乎所有的tomcat操作。如啟動,關閉等等,都是由catalina.bat腳本來完成的。
Catalina.bat腳本解析
Catalina.bat是tomcat所有腳本中最重要的腳本,完成幾乎所有的tomcat操作。如啟動,關閉等等,都是由catalina.bat腳本來完成的。接下來,我將對Tomcat catalina.bat腳本進行分析。
首先省去catalina.bat開頭諸多注解,這些注解主要是講解各個變量是干什么的。
rem Guess CATALINA_HOME if not defined 查看是否在tomcat目錄下,與startup.bat里相同,不解釋了。
set CURRENT_DIR=%cd%
if not "%CATALINA_HOME%" == "" goto gotHome
set CATALINA_HOME=%CURRENT_DIR%
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set CATALINA_HOME=%cd%
cd %CURRENT_DIR%
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHomerem Get standard environment variables
if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" 如果存在setenv.bat腳本,調用它,我的tomcat 沒有這個腳本rem Get standard Java environment variables
if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath 查看是否存在setclasspath.bat腳本,如果存在,轉到okSetclasspath位置
echo Cannot find %CATALINA_HOME%\bin\setclasspath.bat 否則輸出下面兩行,並退出
echo This file is needed to run this program
goto end
:okSetclasspath okSetclasspath位置set BASEDIR=%CATALINA_HOME% 設定BASEDIR變量與CATALINA_HOME變量值相同
call "%CATALINA_HOME%\bin\setclasspath.bat" %1 調用setclasspath.bat腳本並加上參數
if errorlevel 1 goto end 如果存在錯誤 退出rem Add on extra jar files to CLASSPATH 設定JSSE_HOME變量,如果存在加入CLASSPATH,不存在跳過
if "%JSSE_HOME%" == "" goto noJsse 檢查是否存在JSSE_HOME變量
set CLASSPATH=%CLASSPATH%;%JSSE_HOME%\lib\jcert.jar;%JSSE_HOME%\lib\jnet.jar;%JSSE_HOME%\lib\jsse.jar 如果有加入到CLASSPATH變量后面
:noJsse
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\bootstrap.jar 將bootstrap.jar加入到CLASSPATH里if not "%CATALINA_BASE%" == "" goto gotBase 如果CATALINA_BASE變量不為空,跳過,轉到gotBase位置
set CATALINA_BASE=%CATALINA_HOME% 如果為空,將CATALINA_BASE設為CATALINA_HOME變量的值
:gotBaseif not "%CATALINA_TMPDIR%" == "" goto gotTmpdir CATALINA_TMPDIR不為空,跳過,轉到gotTmpdir位置
set CATALINA_TMPDIR=%CATALINA_BASE%\temp 如果為空,將 CATALINA_TMPDIR設為%CATALINA_BASE%\temp變量的值(即tomcat\temp)
:gotTmpdirif not exist "%CATALINA_HOME%\bin\tomcat-juli.jar" goto noJuli 如果不存在tomcat-juli.jar這個類,轉到noJuli位置
set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager - Djava.util.logging.config.file="%CATALINA_BASE%\conf \logging.properties" 如果存在,將變量加入到JAVA_OPTS里
:noJuliset JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m -Dfile .encoding=UTF8 -Duser.timezone=GMT -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config 設定JAVA_OPTS變量
echo Using CATALINA_BASE: %CATALINA_BASE% 輸出CATALINA_BASE變量值
echo Using CATALINA_HOME: %CATALINA_HOME% 輸出CATALINA_HOME變量值
echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR% 輸出CATALINA_TMPDIR變量值
if ""%1"" == ""debug"" goto use_jdk 如果變量%1里存在debug ,轉到use_jdk位置
echo Using JRE_HOME: %JRE_HOME% 輸出JRE_HOME變量值
goto java_dir_displayed 轉到java_dir_displayed
:use_jdk
echo Using JAVA_HOME: %JAVA_HOME% 輸出JAVA_HOME變量值
:java_dir_displayed
下面幾行設定相應變量
set _EXECJAVA=%_RUNJAVA%
set MAINCLASS=org.apache.catalina.startup.Bootstrap
set ACTION=start
set SECURITY_POLICY_FILE=
set DEBUG_OPTS=
set JPDA=if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_shmem
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=jdbconn
:gotJpdaAddress
if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend
set JPDA_SUSPEND=n
:gotJpdaSuspend
if not "%JPDA_OPTS%" == "" goto gotJpdaOpts
set JPDA_OPTS=-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
:gotJpdaOpts
shift
:noJpdaif ""%1"" == ""debug"" goto doDebug 如果%1為debug,轉到doDebug,運行debug模式
if ""%1"" == ""run"" goto doRun 如果%1為run,轉到doRun,運行正常模式
if ""%1"" == ""start"" goto doStart 如果%1為start,轉到doStart,啟動tomcat
if ""%1"" == ""stop"" goto doStop 如果%1為stop,轉到doStop,關閉tocmat
if ""%1"" == ""version"" goto doVersion 如果%1為version,轉到doVersion,顯示tomcat的版本號echo Usage: catalina ( commands ... ) 如果%1沒有上述內容,輸出下面幾行,並結束
echo commands:
echo debug Start Catalina in a debugger
echo debug -security Debug Catalina with a security manager
echo jpda start Start Catalina under JPDA debugger
echo run Start Catalina in the current windowecho run -security Start in the current window with security manager
echo start Start Catalina in a separate window
echo start -security Start in a separate window with security manager
echo stop Stop Catalina
echo version What version of tomcat are you running?
goto end:doDebug
shift 將%2里的值轉到%1
set _EXECJAVA=%_RUNJDB% 將變量 _EXECJAVA設為_RUNJDB變量的值
set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%....\jakarta-tomcat-catalina\catalina\src\share"
設定DEBUG_OPTS變量if not ""%1"" == ""-security"" goto execCmd
如果%1不為-security,轉到execCmd位置shift 將%2里的值轉到%1
echo Using Security Manager 輸出該行
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy
設定SECURITY_POLICY_FILE變量的值goto execCmd 轉到execCmd位置
:doRun
shift 將%2里的值轉到%1
if not ""%1"" == ""-security"" goto execCmd 如果%1不為-security,轉到execCmd位置
shift 將%2里的值轉到%1
echo Using Security Manager 輸出該行
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy
設定SECURITY_POLICY_FILE變量的值goto execCmd 轉到execCmd位置
:doStart
shift 將%2里的值轉到%1
if not "%OS%" == "Windows_NT" goto noTitle 如果OS變量不為Windows_NT,轉到noTitle
set _EXECJAVA=start "Tomcat" %_RUNJAVA% 設定_EXECJAVA變量的值
goto gotTitle 轉到gotTitle位置
:noTitle
set _EXECJAVA=start %_RUNJAVA% 設定 _EXECJAVA 變量的值
:gotTitle
if not ""%1"" == ""-security"" goto execCmd 如果%1不為-security,轉到execCmd位置
shift 將%2里的值轉到%1
echo Using Security Manager 輸出該行
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy
設定SECURITY_POLICY_FILE變量的值goto execCmd 轉到execCmd位置
:doStop
shift 將%2里的值轉到%1
set ACTION=stop 將ACTION的變量設為stop
set CATALINA_OPTS= 設CATALINA_OPTS為空goto execCmd 轉到execCmd位置
:doVersion 顯示tomcat版本號
%_EXECJAVA% -classpath "%CATALINA_HOME%\server\lib\catalina.jar" org.apache.catalina.util.ServerInfo 執行該命令
goto end 結束該程序:execCmd
rem Get remaining unshifted command line arguments and save them in the
以下幾行將命令參數存入CMD_LINE_ARGS變量中set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgsrem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda 如果JPDA變量不為空,轉到doJpda位置
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
如果SECURITY_POLICY_FILE變量不為空,轉到doSecurity位置如果都沒有執行下面命令,並結束該程序
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurity 執行下面命令,並結束該程序
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doJpda
如果SECURITY_POLICY_FILE變量不為空,轉到doSecurityJpda位置,為空執行下面命令,並結束該程序if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurityJpda 執行下面命令,並結束該程序
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end:end
tomcat相關配置文件
- 即使不細看,也可以知道其中會調用相關的配置文件以啟動相關的服務,那么,相關的服務在哪里呢,我們需要知道tomcat服務器的總的存貯目錄的功能
- 出現端口相關的問題,肯定在配置文件中,其中配置文件中最重要的便是server.xml和web.xml
tomcat整體架構
- 要想理解這兩個文件的作用,首先要認識tomcat的整體架構
Server 表示整個servlet容器,因此Tomcat容器中只有一個Server實例
Service 表示一個或多個Connector的集合。這些Connector共享同一個Container來處理其他請求。在一個Server中可以包含多個Service,這些Service相互獨立
Connector Tomcat連接器,用於監聽並轉換為Socket請求,將該請求交由Container處理,支持不同的協議及不同IO方式
Container 表示能夠接收請求並返回響應的一類對象。在Tomcat中存在不同級別的容器:Engine、Host、Context、Wrapper
Engine 表示整個Servlet引擎,Engine為最高級別的容器。盡量Engine不是直接處理請求的容器卻是獲得目標容器的入口
Host 表示Engine中的虛擬機,與一個服務器的網絡名有關,如域名等。客戶端可以使用這個網絡名連接服務器,這個名稱必須要在DNS服務器上注冊
Context 用於表示ServletContext,在Servlet規范中,一個ServletContext表示一個Web應用
Wrapper 表示Web應用中定義的Servlet
Executor 表示Tomcat組件間可以共享的線程池
server.xml和web.xml
- 因此我們可以大致猜到Server.xml的作用,我們出現問題的地方也在這里了,若是我們設置了不同http port,繞過了idea的端口檢測,且啟動同一個catalina.bat,我們將讀取同一個Server.xml文件,那我們的server 端口將會重復,出現:InstanceNotFoundException: Catalina:type=Server(即catalina在server創建階段出現錯誤,無法找到相應實例),其中server的識別是依據相應的端口號來識別的,而相同的catalina.bat的啟動導致讀取的server.xml仍是相同的server端口號,導致異常
- 解決方案便是:啟動時兩個服務器各自應用兩個獨立的tomcat服務器文件,或者修改catalina.bat(並創建另外的server文件),使其第二次啟動時跳過已被占用了的端口文件,讀取其他的配置。所以我選擇了前者。
server.xml的作用:
- 另外還有一個要注意的時這個web.xml,我們在idea或者eclipse中創建的web項目中也包含了web.xml,兩者有什么關系呢
- 這是他們的父類,它里面的配置,如果動態web工程沒有覆蓋,就會被“繼承”下來。我們會發現,conf/web.xml里配置了默認的DefaultServlet(org.apache.catalina.servlets.DefaultServlet,以及一些cgi等)和filter (很多類org.apache.catalina.filters. *)
web.xml的作用:
聯想到SpringMVC
- 這便是web項目中web.xml最原始的模樣,springmvc中的dispatcherServlet也是如此,將匹配到的/路徑下的拿到dispatcherServlet中去轉發或重定位
Web.xml對servlet和Litsener等的讀取方式
- 而若想知道為什么單憑一個鏈接便可以接入到相應的servlet,你便需要了解整個流程
- 我們通過catalina.bat開始創建服務器,將server.xml環境配置完后,tomcat是通過生成一個StandardServer將其與catalina實例綁定,進行注冊等操作后,便會開始部署項目,創建StandardContext
- 部署項目時一個StandardContext便是一個web項目,其會讀取web.xml,最終解析是在
ContextConfig
中的webConfig
方法解析完生成一個WebXml 對象
web.xml加載過程(其中節點的加載順序context-param -> listener -> filter -> servlet )
1.全局默認配置文件:tomcat目錄下conf/web.xml解析為WebXml對象。
2.具體應用程序下的web.xml解析:例 /examples/WEB-INF/web.xml
3.掃描應用程序examples下的所有Jar,查找META-INF/web-fragment.xml
文件並解析,保存到變量fragments中,格式<String,WebXml>。
4.已經檢索到的WebXml配置進行排序。
5.基於SPI機制查找ServletContainerInitializer的實現。
6.掃描/WEB-INF/classes下面的類,處理Annotation:@ WebServlet,@ WebFilter,@ WebListener
7、掃描jar包中的Annotation:web-fragment.xml所在的jar包。
8、合並配置:所有web-fragment.xml中的配置,合並到應用程序examples中的配置web.xml。
9、合並配置:全局默認配置defaults 合並到應用程序的web.xml。
- 接着用這個對象去創建ServletContext(單例共享)
10、將JSP轉換為Servlet。
11、將合並后的最終配置web.xml對象webXml應用到servlet容器(ServletContext),裝配servlet上下文;
12、將配置信息保存容器中,供其他組件訪問,使得其他組件不需要再次重復上面的步驟去獲取配置信息了。
13、查找jar包中的靜態資源。
14、將ServletContainerInitializer應用到上下文。
- 同時StandardContext在讀取web.xml中過的**
創建 中的類實例,創建監聽器。 **** - 有了監聽器,我們便可以監聽有到達我們的端口的消息(url-pattern);有了ServletContext,我們就可以依據相應的相應的servlet-class去執行(或者再經過disparcherServlet去轉發),若是找不到相應的servlet,則會用defaultServlet(連出錯處理的servlet都沒有的情況下)去處理
- 有這種servlet則加入到ServletContext的Map中
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- springmvc將我們配置servlet的步驟省略了,都靠DisparcherServlet接收,並由他進行后續的處理,而我們只需要依照他的應用規則相應的注釋。
- 需要相應實體類便由spring用工廠模式加載到的容器中去調用
- Spring與myBatis的集成便需要細細述說了,但就是Spring的事務管理的基礎上,改換一下sqlsession的創建流程,換一個不同種類的代理類(與.getmapper相似),並用專門的SpringManageTransaction用以獲取保存的connection。
- 而上面這個Spring與myBatis的集成就是真正的慘案了
https://www.cnblogs.com/eternal-heathens/p/13391261.html