The reason has been found and a litter complex as following:
While deploying a wab, a OSGiDeploymentContext instance will be created and a WABClassLoader will be setuped by calling setupClassLoader(). Then, while accessing WAB resouces(eg. localhost:8080/uas/), WEB-INF/lib/*.jars will be scanned and opened(eg. calling org.glassfish.web.loader.WebappClassLoader.openJARs()). What's more, these jars must be opened alway in order to service WAB resources.
Then, while undeploying the wab, we must execute org.glassfish.web.loader.WebappClassLoader.closeJARS(true) or stop() in order to release these WEB-INF/lib/.jars resources. I have made such an experiment on OSGiWebUndeploymentRequest class and obtain the setuped WABClassloader to execute closeJARS(true) by OSGiUndeploymentRequest's dc field(I modified it into protected access level), however, these WEB-INF/lib/.jars resources are not still closed.
Next, I start to guess a thing that the WABClassloader I obtained by dc.getFinalClassLoader() is not the same as the WABClassloader which is setuped by the OSGiDeploymentContext instance. And by confirming WABClassLoader instance id, I can confirm the guess is right.
That is to say, OSGiUndeploymentRequest.getDeploymentContextImpl will create a new OSGiDeploymentContext and WABClassloader instance and is different from OSGiDeploymentRequest.getDeploymentContextImpl.
In a word, here there is a jar resource leak caused by a WABClassLoader while undeploying a wab.
While undeploying the wab, we must obtain the same WABClassLoader as deploying the wab. So, I consider to register the WABClassLoader into OSGi Registry with propery WabId="<the wab bundle id>", then, executing closeJARS(true).
Please Sahoo seeing what I said and maybe I have not said clearly.