I am using groovy to execute a set of groovy scripts, which works fine when the runtime jar is deployed with the webapp and the runtime executes the groovy scripts present under C:\jboss-eap-7.4\bin (java working directory). Due to portability and other constraints now we need to move these groovy scripts as part of the runtime jar and then load and execute these scripts from the class path.
Can anyone help in running the groovy scripts present inside the runtime jar file (within the webapp)?
The current implementation that executes the groovy scripts from C:\jboss-eap-7.4\bin (java working directory)
** Updated after aswer given by 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 method
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 []
}
Test Run Command: 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 %*
** Old Update**
At present with the above code, if I place the plugins folder (groovy script) inside the jar, it says it cannot find Plugins.groovy under C:\jboss-eap-7.4\bin
folder
Screenshot of jar inside war file C:\Users\ricky\Desktop\siperian-mrm.ear\mysupport.war\WEB-INF\lib\runtime.jar\
The answers provided above are also correct, particularly those provided by @daggett, as they include multiple ways to read/access a resource from within a jar file. I'm sharing my version, which has been tested on this codebase.
I made the following changes
Modified the pom.xml to include the "plugins" folder instead of individual groovy scripts. <include>plugins/</include>
Using getResourceAsStream
something like below to read the scripts.
StringBuilder pluginsDir = new StringBuilder(System.getProperty("plugins_dir").toString()) String script = pluginsDir.append(script) InputStream inputStream = getClass().getResourceAsStream(script) BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)) pluginScript = groovyShell.parse(reader); return pluginScript
Using below command to run
java -cp mvn-groovy-test-example-1.0-jar-with-dependencies.jar; -Dplugins_dir=/plugins/ com.example.App