gpt4 book ai didi

java - 如何从 jar 文件中加载 groovy 脚本?

转载 作者:行者123 更新时间:2023-12-05 02:25:30 30 4
gpt4 key购买 nike

我正在使用 groovy 执行一组 groovy 脚本,当运行时 jar 与 webapp 一起部署并且运行时执行 C:\jboss-eap-7.4\bin(java 工作目录)下的 groovy 脚本时,它工作正常).由于可移植性和其他限制,现在我们需要将这些 groovy 脚本作为运行时 jar 的一部分移动,然后从类路径加载并执行这些脚本。

任何人都可以帮助运行运行时 jar 文件(在 webapp 中)中存在的 groovy 脚本吗?

enter image description here

当前从 C:\jboss-eap-7.4\bin(java 工作目录)执行 groovy 脚本的实现

** 在 GPT-3 给出答案后更新**

final String PLUGIN_DESCRIPTOR = "Plugins.groovy"
final class PluginBootStrapper
{
private GroovyScriptEngine scriptEngine = null;
private GroovyShell shell;
private GroovyClassLoader classLoader = null;
private final boolean loadFromClasspath;

private final List<Plugin> allPlugins = null;

private static final Logger logger = LogManager.getLogger(PluginBootStrapper.class);

public PluginBootStrapper()
{
System.out.println("Inside PluginBootStrapper")
logger.info("Inside PluginBootStrapper")
String pluginsDir = System.getProperty(CSMProperties.endorsed_plugins_dir)//".\\plugins"//System.getProperty(CSMProperties.endorsed_plugins_dir)
loadFromClasspath = true
shell = new GroovyShell();
//scriptEngine = new GroovyScriptEngine(CommonUtils.getAllDirectories(pluginsDir))

logger.info "Plugins Directory:"+pluginsDir
println "Plugins Directory:"+pluginsDir

allPlugins = loadDescriptor().invokeMethod("getAllPlugins", null)
}

private Object loadDescriptor()
{
Object pluginDescriptor = bootStrapScript(CSMProperties.get(CSMProperties.PLUGIN_DESCRIPTOR))
pluginDescriptor
}

Object bootStrapScript(String script)
{
String pluginsDir = System.getProperty(CSMProperties.endorsed_plugins_dir)
if (pluginsDir != null) {
script = pluginsDir + script
}

printClassPath(this.class.getClassLoader())

Object pluginScript = null
//logger.info "script: "+ script
//String path = this.getClass().getClassLoader().getResource(script).toExternalForm()
//logger.info "bootStrapScript script "+ script
logger.info "bootStrapScript script: "+ script + ", path: "+ new File(script).absolutePath
println "bootStrapScript script: "+ script + ", path: "+ new File(script).absolutePath
if (this.loadFromClasspath) {
pluginScript = new GroovyShell(this.class.getClassLoader()).evaluate(new File(script)); //<-- Line no:60
/* classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
pluginScript = classLoader.parseClass(new File(script)); */
return pluginScript
} else {
pluginScript = scriptEngine.loadScriptByName(script).newInstance()
return pluginScript
}

return pluginScript
}

public List<Plugin> getAllPlugins()
{
return allPlugins
}

def printClassPath(classLoader) {
println "$classLoader"
classLoader.getURLs().each {url->
println "- ${url.toString()}"
}
if (classLoader.parent) {
printClassPath(classLoader.parent)
}
}

}

CommonUtils.getAllDirectories 方法

public static String[] getAllDirectories(String directory)
{
logger.info("Inside CommonUtils"+directory)
def dir = new File(directory)
def dirListing = []
if (dir.exists()) {
logger.info "Looking for plugins in "+dir.absolutePath+" directory."

dir.eachFileRecurse {file->
if(file.isDirectory()) {
dirListing << file.getPath()
logger.info "Using "+file.getPath()+" plugin folder."
} else {
logger.info "Using "+file.getPath()+" plugin file."
}
}
} else {
logger.error directory+" folder does not exist. Please provide the plugin files."
}

dirListing.toArray() as String []
}

测试运行命令:java -cp runtime-2.0-jar-with-dependencies.jar;.runtime-2.0-jar-with-dependencies.jar; -Dendorsed_plugins_dir=runtime-2.0-jar-with-dependencies.jar\com.Main %*

输出 enter image description here

** 旧更新**

目前使用上面的代码,如果我将插件文件夹(groovy 脚本)放在 jar 中,它说它无法在 C:\jboss-eap-7.4\bin 下找到 Plugins.groovy文件夹

war 文件中的 jar 截图C:\Users\ricky\Desktop\siperian-mrm.ear\mysupport.war\WEB-INF\lib\runtime.jar\ enter image description here

最佳答案

假设您有包含以下 groovy 文件的 plugins.jar

/a/b/C.groovy

def f(x){
println "${this.getClass()} :: ${x}"
}

选项 1

//in this case you don't need plugins.jar to be in classpath
//you should detect somehow where the plugins.jar is located for current runtime
URL jar = new URL('jar:file:./plugins.jar!/') //jar url must end with !/
def groovyScriptEngine = new GroovyScriptEngine(jar)
def C = groovyScriptEngine.loadScriptByName('a/b/C.groovy')
def c = C.newInstance()
c.f('hello world')

选项 2

//plugins.jar must be in current classpath
//C.groovy must have a `package` header if it's located in /a/b folder: package a.b
def C = this.getClass().getClassLoader().loadClass('a.b.C')
def c = C.newInstance()
c.f('hello world')

选项 3

//plugins.jar must be in current classpath
def url = this.getClass().getClassLoader().getResource('a/b/C.groovy')
def gshell = new GroovyShell()
def c = gshell.parse(url.toURI())
c.f('hello world')

迭代 jar 中的文件

理论上可以列出 jar 中的文件,但是应用程序服务器可能对此有限制。

在获得入口点 - 类/脚本实例 a/b/C.groovy(在您的情况下为“Plugins.groovy”)之后,您可以获得对 jar 的引用并迭代条目:

URL jar = c.getClass().protectionDomain.codeSource.location //you don't need this for option #1

JarURLConnection jarConnection = (JarURLConnection)url.openConnection()
jarConnection.getJarFile().with{jarFile->
jarFile.entries().each{java.util.jar.JarEntry e->
println e.getName()
if(!e.isDirectory()){
//you can load/run script here instead of printing it
println '------------------------'
println jarFile.getInputStream(e).getText()
println '------------------------'
}
}
}

关于java - 如何从 jar 文件中加载 groovy 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74569226/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com