我正在使用Groovy执行一组Groovy脚本,当运行时JAR与Web应用程序一起部署并且运行时执行位于C:\ jboss-eap-7.4 \ bin(Java工作目录)下的Groovy脚本时,这些脚本可以正常工作。由于可移植性和其他限制,现在我们需要将这些Groovy脚本作为运行时JAR的一部分移动,然后从类路径加载和执行这些脚本。
有人可以帮助运行运行时JAR文件内部的Groovy脚本吗(在Web应用程序中)?
目前的实现是从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 %*
**旧更新**
目前,如果我将插件文件夹(Groovy脚本)放在jar包中,它会说找不到C:\jboss-eap-7.4\bin
文件夹下的Plugins.groovy
Jar包内war文件的截图:C:\Users\ricky\Desktop\siperian-mrm.ear\mysupport.war\WEB-INF\lib\runtime.jar\
new plugins.desc.Plugins()
来实例化/plugins/desc/Plugins.groovy
呢? - daggettnew a.b.Plugins()
语句?它甚至可以从jar文件中加载Groovy类... - daggettsomeClass.getClass().protectionDomain.codeSource.location
获取JAR位置,然后尝试使用https://docs.oracle.com/javase/8/docs/api/java/util/zip/ZipFile.html列出JAR内容。你的其余代码应该可以工作,但从ZipEntry获取脚本内容或使用ClassLoader作为资源,或者像我说的那样,你可以直接使用`currentGroovyClassLoader.loadClass('plugins.desc.Plugins')` - 但在这种情况下,它应该有声明的包... - daggett