fdo#46102: Load Java scripts with class loaders that actually find them
ScriptMetaData.createURL produces weird URLs (ending in "/ucb/", and potentially still containing vnd.sun.star.expand: prefix) that are apparently good for loading documents for editing via UCBStreamHandler, but cannot meaningfully be passed to a URLClassLoader. It is unclear to me how the Java script provider shall ever have found the script jars in the past.
This commit is contained in:
@@ -50,7 +50,14 @@ import com.sun.star.script.framework.io.UCBStreamHandler;
|
|||||||
|
|
||||||
import com.sun.star.ucb.XSimpleFileAccess2;
|
import com.sun.star.ucb.XSimpleFileAccess2;
|
||||||
|
|
||||||
|
import com.sun.star.uno.AnyConverter;
|
||||||
import com.sun.star.uno.UnoRuntime;
|
import com.sun.star.uno.UnoRuntime;
|
||||||
|
import com.sun.star.uno.XComponentContext;
|
||||||
|
|
||||||
|
import com.sun.star.uri.UriReferenceFactory;
|
||||||
|
import com.sun.star.uri.XVndSunStarExpandUrl;
|
||||||
|
|
||||||
|
import com.sun.star.util.XMacroExpander;
|
||||||
|
|
||||||
public class ScriptMetaData extends ScriptEntry implements Cloneable {
|
public class ScriptMetaData extends ScriptEntry implements Cloneable {
|
||||||
private boolean hasSource = false;
|
private boolean hasSource = false;
|
||||||
@@ -246,7 +253,8 @@ public class ScriptMetaData extends ScriptEntry implements Cloneable {
|
|||||||
return "\nParcelLocation = " + getParcelLocation() + "\nLocationPlaceHolder = " + locationPlaceHolder + super.toString();
|
return "\nParcelLocation = " + getParcelLocation() + "\nLocationPlaceHolder = " + locationPlaceHolder + super.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL[] getClassPath() throws java.net.MalformedURLException
|
public URL[] getClassPath(XComponentContext context)
|
||||||
|
throws java.net.MalformedURLException
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -274,7 +282,7 @@ public class ScriptMetaData extends ScriptEntry implements Cloneable {
|
|||||||
{
|
{
|
||||||
String relativeClasspath = (String)stk.nextElement();
|
String relativeClasspath = (String)stk.nextElement();
|
||||||
String pathToProcess = PathUtils.make_url( parcelPath, relativeClasspath);
|
String pathToProcess = PathUtils.make_url( parcelPath, relativeClasspath);
|
||||||
URL url = createURL( pathToProcess );
|
URL url = expandURL( context, pathToProcess );
|
||||||
if ( url != null )
|
if ( url != null )
|
||||||
{
|
{
|
||||||
classPathVec.add ( url );
|
classPathVec.add ( url );
|
||||||
@@ -283,7 +291,7 @@ public class ScriptMetaData extends ScriptEntry implements Cloneable {
|
|||||||
}
|
}
|
||||||
if ( classPathVec.size() == 0)
|
if ( classPathVec.size() == 0)
|
||||||
{
|
{
|
||||||
URL url = createURL( parcelPath );
|
URL url = expandURL( context, parcelPath );
|
||||||
if ( url != null )
|
if ( url != null )
|
||||||
{
|
{
|
||||||
classPathVec.add(url);
|
classPathVec.add(url);
|
||||||
@@ -300,6 +308,38 @@ public class ScriptMetaData extends ScriptEntry implements Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private URL expandURL(XComponentContext context, String url)
|
||||||
|
throws java.net.MalformedURLException
|
||||||
|
{
|
||||||
|
XVndSunStarExpandUrl exp = UnoRuntime.queryInterface(
|
||||||
|
XVndSunStarExpandUrl.class,
|
||||||
|
UriReferenceFactory.create(context).parse(url));
|
||||||
|
String expurl;
|
||||||
|
if (exp == null) {
|
||||||
|
expurl = url;
|
||||||
|
} else {
|
||||||
|
XMacroExpander expander;
|
||||||
|
try {
|
||||||
|
expander = (XMacroExpander) AnyConverter.toObject(
|
||||||
|
XMacroExpander.class,
|
||||||
|
context.getValueByName(
|
||||||
|
"/singletons/com.sun.star.util.theMacroExpander"));
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
expurl = exp.expand(expander);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
java.net.MalformedURLException e2 =
|
||||||
|
new java.net.MalformedURLException(e.toString());
|
||||||
|
e2.initCause(e);
|
||||||
|
throw e2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new URL(expurl);
|
||||||
|
}
|
||||||
|
|
||||||
private URL createURL( String path ) throws java.net.MalformedURLException
|
private URL createURL( String path ) throws java.net.MalformedURLException
|
||||||
{
|
{
|
||||||
URL url = null;
|
URL url = null;
|
||||||
|
@@ -31,6 +31,7 @@ import java.net.*;
|
|||||||
|
|
||||||
import com.sun.star.script.framework.log.LogUtils;
|
import com.sun.star.script.framework.log.LogUtils;
|
||||||
import com.sun.star.script.framework.container.ScriptMetaData;
|
import com.sun.star.script.framework.container.ScriptMetaData;
|
||||||
|
import com.sun.star.uno.XComponentContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Loader Factory
|
* Class Loader Factory
|
||||||
@@ -42,11 +43,12 @@ public class ClassLoaderFactory
|
|||||||
{
|
{
|
||||||
private ClassLoaderFactory() {}
|
private ClassLoaderFactory() {}
|
||||||
|
|
||||||
public static ClassLoader getURLClassLoader( ScriptMetaData scriptData )
|
public static ClassLoader getURLClassLoader(
|
||||||
|
XComponentContext context, ScriptMetaData scriptData )
|
||||||
throws NoSuitableClassLoaderException, MalformedURLException
|
throws NoSuitableClassLoaderException, MalformedURLException
|
||||||
{
|
{
|
||||||
ClassLoader parent = scriptData.getClass().getClassLoader();
|
ClassLoader parent = scriptData.getClass().getClassLoader();
|
||||||
URL[] classPath = scriptData.getClassPath();
|
URL[] classPath = scriptData.getClassPath(context);
|
||||||
LogUtils.DEBUG("Classpath has length " + classPath.length );
|
LogUtils.DEBUG("Classpath has length " + classPath.length );
|
||||||
for ( int i=0; i < classPath.length; i++ )
|
for ( int i=0; i < classPath.length; i++ )
|
||||||
{
|
{
|
||||||
|
@@ -202,7 +202,8 @@ public class ScriptEditorForBeanShell
|
|||||||
try {
|
try {
|
||||||
ClassLoader cl = null;
|
ClassLoader cl = null;
|
||||||
try {
|
try {
|
||||||
cl = ClassLoaderFactory.getURLClassLoader( entry );
|
cl = ClassLoaderFactory.getURLClassLoader(
|
||||||
|
context.getComponentContext(), entry );
|
||||||
}
|
}
|
||||||
catch (Exception ignore) // TODO re-examine error handling
|
catch (Exception ignore) // TODO re-examine error handling
|
||||||
{
|
{
|
||||||
|
@@ -196,7 +196,8 @@ class ScriptImpl implements XScript
|
|||||||
ClassLoader cl = null;
|
ClassLoader cl = null;
|
||||||
URL sourceUrl = null;
|
URL sourceUrl = null;
|
||||||
try {
|
try {
|
||||||
cl = ClassLoaderFactory.getURLClassLoader( metaData );
|
cl = ClassLoaderFactory.getURLClassLoader(
|
||||||
|
m_xContext, metaData );
|
||||||
sourceUrl = metaData.getSourceURL();
|
sourceUrl = metaData.getSourceURL();
|
||||||
}
|
}
|
||||||
catch ( java.net.MalformedURLException mfu )
|
catch ( java.net.MalformedURLException mfu )
|
||||||
|
@@ -205,7 +205,7 @@ class ScriptImpl implements XScript
|
|||||||
try {
|
try {
|
||||||
LogUtils.DEBUG( "Classloader starting..." );
|
LogUtils.DEBUG( "Classloader starting..." );
|
||||||
scriptLoader = ClassLoaderFactory.getURLClassLoader(
|
scriptLoader = ClassLoaderFactory.getURLClassLoader(
|
||||||
metaData );
|
m_xContext, metaData );
|
||||||
LogUtils.DEBUG( "Classloader finished..." );
|
LogUtils.DEBUG( "Classloader finished..." );
|
||||||
}
|
}
|
||||||
catch (MalformedURLException mfe )
|
catch (MalformedURLException mfe )
|
||||||
|
@@ -195,7 +195,8 @@ class ScriptImpl implements XScript
|
|||||||
ClassLoader cl = null;
|
ClassLoader cl = null;
|
||||||
URL sourceUrl = null;
|
URL sourceUrl = null;
|
||||||
try {
|
try {
|
||||||
cl = ClassLoaderFactory.getURLClassLoader( metaData );
|
cl = ClassLoaderFactory.getURLClassLoader(
|
||||||
|
m_xContext, metaData );
|
||||||
sourceUrl = metaData.getSourceURL();
|
sourceUrl = metaData.getSourceURL();
|
||||||
}
|
}
|
||||||
catch ( java.net.MalformedURLException mfu )
|
catch ( java.net.MalformedURLException mfu )
|
||||||
|
Reference in New Issue
Block a user