1. 程式人生 > >Jetty多專案啟動時的衝突問題

Jetty多專案啟動時的衝突問題

通過main啟動多專案Jetty時碰到了lib衝突的問題,如下面這個異常

Invocation of init method failed; nested exception is java.lang.SecurityException: sealing violation: package oracle.jdbc.driver is sealed

下面是我啟動用的程式碼

Server server = new Server(HTTPPORT);

WebAppContext webContext = new WebAppContext("src/main/webapp", CONTEXT);
        webContext.setClassLoader(Thread.currentThread().getContextClassLoader());

WebAppContext other = new
WebAppContext(); other.setWar("../other.war"); other.setContextPath("/other"); server.addHandler(webContext); server.addHandler(other); server.setStopAtShutdown(true); server.start(); server.join();

因為當前工程和other是用同一套lib,打包時被打進了war,又不想全部拆出來處理,結果就得到了上面的異常。這種衝突的異常表現形式不唯一,大體都能猜出來是同一個原因。查了各種方案也沒明確說明怎麼解決這個問題,難道要去看原始碼了麼?懶蛋的我靈光一現!

server.addHandler(other);
server.addHandler(webContext);

把順序調換一下,成功!

萬萬沒想到這篇部落格還有二週目

原因是這樣的,在成功調整了Jetty的啟動順序後,兩個專案已經可以和諧共存了,controller,service,dao看起來是那麼的美好。然而這美好並沒有持續太久,在一個aop的午後,平靜被打破了。

[org.springframework.web.context.support.XmlWebApplicationContext] Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with
name 'tableDao': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private xxxxxxxxxx.Dialect yyyyyyy.dialect; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [xxxxxxxxxx.Dialect] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)

這麼個奇怪的報錯,不由得虎軀一震。看前面的日誌資訊,是jetty在解包war工程,並且載入完xml以後,掃描了當前工程的class檔案。

臥槽!這不科學!
翻看Jetty的API沒找到怎麼設定獨立上下文的辦法,耗時2days+

不能夠,一定有解決辦法,於是開debug看jetty載入流程。終於debug到spring的載入層,發現war工程spring在載入xml時,會根據classpath*: 這個引數在每個工程裡找,也就是除了當前要處理的war工程,也會查詢當前工程。而我要載入的這兩個工程的結構是差不多的,spring配置都寫在了一個叫spring的資料夾下。

雖然沒找到怎麼分隔上下文,但是我可以把資料夾變更為獨立的,然後在各自工程下將component-scan限制到精確路徑。再次載入果然解決了這個問題。

別再來三週目了,傷不起