Skip to content

Commit

Permalink
Ensures classloader always present for UDFSource and SystemFunctionMa…
Browse files Browse the repository at this point in the history
…nager

* Since the loading of classes reflectively is so important for teiid
  functions, a classloader must be available to allow the plugin to find
  the necessary classes.

* Product of executing all designer tests so fixes to ensure all pass
  • Loading branch information
Paul Richardson committed Apr 4, 2014
1 parent 557740d commit a4b9da2
Show file tree
Hide file tree
Showing 12 changed files with 25 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ public class SystemFunctionManager {

private FunctionTree systemFunctionTree;
private boolean allowEnvFunction = true;
private ClassLoader classLoader;
private final ClassLoader classLoader;
private final ITeiidServerVersion teiidVersion;

/**
* @param teiidVersion
* @param classLoader
*/
public SystemFunctionManager(ITeiidServerVersion teiidVersion) {
public SystemFunctionManager(ITeiidServerVersion teiidVersion, ClassLoader classLoader) {
this.teiidVersion = teiidVersion;
this.classLoader = classLoader;
}

/**
Expand All @@ -55,8 +57,7 @@ public ITeiidServerVersion getTeiidVersion() {
public FunctionTree getSystemFunctions() {
if(systemFunctionTree == null) {
// Create the system source and add it to the source list
SystemSource systemSource = new SystemSource(getTeiidVersion(), this.allowEnvFunction);
systemSource.setClassLoader(classLoader);
SystemSource systemSource = new SystemSource(getTeiidVersion(), this.allowEnvFunction, classLoader);
// Validate the system source - should never fail
ValidatorReport report = new ValidatorReport("Function Validation"); //$NON-NLS-1$
Collection<FunctionMethod> functionMethods = systemSource.getFunctionMethods();
Expand Down Expand Up @@ -85,8 +86,4 @@ public void setAllowEnvFunction(boolean allowEnvFunction) {
public ClassLoader getClassLoader() {
return this.classLoader;
}

public void setClassloader(ClassLoader classloader) {
this.classLoader = classloader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
package org.teiid.query.function;

import java.util.Collection;

import org.teiid.metadata.FunctionMethod;

public class UDFSource implements FunctionMetadataSource {

protected Collection <FunctionMethod> functions;
private ClassLoader classLoader;
private final ClassLoader classLoader;

public UDFSource(Collection <FunctionMethod> methods) {
public UDFSource(Collection <FunctionMethod> methods, ClassLoader classLoader) {
this.functions = methods;
this.classLoader = classLoader;
}

public Collection<FunctionMethod> getFunctionMethods() {
Expand All @@ -43,10 +43,6 @@ public Class<?> getInvocationClass(String className) throws ClassNotFoundExcepti
return Class.forName(className, true, classLoader==null?Thread.currentThread().getContextClassLoader():classLoader);
}

public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}

public ClassLoader getClassLoader() {
return classLoader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ public class SystemSource extends UDFSource implements FunctionCategoryConstants
*
* @param teiidVersion
* @param allowEnvFunction
* @param classLoader
*/
public SystemSource(ITeiidServerVersion teiidVersion, boolean allowEnvFunction) {
super(new ArrayList<FunctionMethod>());
public SystemSource(ITeiidServerVersion teiidVersion, boolean allowEnvFunction, ClassLoader classLoader) {
super(new ArrayList<FunctionMethod>(), classLoader);
this.teiidVersion = teiidVersion;
this.dataTypeManager = DataTypeManagerService.getInstance(teiidVersion);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ public SystemMetadata(ITeiidServerVersion teiidVersion) {
systemStore = loadSchema(vdb, p, resourceLocation, "SYS", parser).asMetadataStore(); //$NON-NLS-1$
systemStore.addDataTypes(dataTypes);
loadSchema(vdb, p, resourceLocation, "SYSADMIN", parser).mergeInto(systemStore); //$NON-NLS-1$
TransformationMetadata tm = new TransformationMetadata(parser.getTeiidParser(), vdb, new CompositeMetadataStore(systemStore), null, new SystemFunctionManager(teiidVersion).getSystemFunctions(), null);
SystemFunctionManager systemFunctionManager = new SystemFunctionManager(teiidVersion, getClass().getClassLoader());
TransformationMetadata tm = new TransformationMetadata(parser.getTeiidParser(), vdb, new CompositeMetadataStore(systemStore), null, systemFunctionManager.getSystemFunctions(), null);
vdb.addAttchment(IQueryMetadataInterface.class, tm);
MetadataValidator validator = new MetadataValidator(this.teiidVersion, this.typeMap);
ValidatorReport report = validator.validate(vdb, systemStore);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public class QueryService implements IQueryService {
*/
public QueryService(ITeiidServerVersion teiidVersion) {
this.teiidVersion = teiidVersion;
systemFunctionManager = new SystemFunctionManager(teiidVersion);
systemFunctionManager = new SystemFunctionManager(teiidVersion, getClass().getClassLoader());
}

/**
Expand Down Expand Up @@ -134,14 +134,6 @@ public String getJDBCSQLTypeName(int jdbcType) {

@Override
public IFunctionLibrary createFunctionLibrary() {
/*
* System function manager needs this classloader since it uses reflection to instantiate classes,
* such as FunctionMethods. The default classloader is taken from the thread, which in turn takes
* a random plugin. Since no plugin depends on this plugin, ClassNotFound exceptions result.
*
* So set the class loader to the one belonging to this plugin.
*/
systemFunctionManager.setClassloader(getClass().getClassLoader());
return new FunctionLibrary(teiidVersion, systemFunctionManager.getSystemFunctions(), new FunctionTree[0]);
}

Expand Down Expand Up @@ -176,22 +168,14 @@ public IFunctionLibrary createFunctionLibrary(List<FunctionMethodDescriptor> fun

FunctionTree tree = functionTrees.get(descriptor.getSchema());
if (tree == null) {
tree = new FunctionTree(teiidVersion, descriptor.getSchema(), new UDFSource(Collections.EMPTY_LIST), false);
tree = new FunctionTree(teiidVersion, descriptor.getSchema(), new UDFSource(Collections.EMPTY_LIST, getClass().getClassLoader()), false);
functionTrees.put(descriptor.getSchema(), tree);
}

FunctionDescriptor fd = tree.addFunction(descriptor.getSchema(), null, fMethod, false);
fd.setMetadataID(descriptor.getMetadataID());
}

/*
* System function manager needs this classloader since it uses reflection to instantiate classes,
* such as FunctionMethods. The default classloader is taken from the thread, which in turn takes
* a random plugin. Since no plugin depends on this plugin, ClassNotFound exceptions result.
*
* So set the class loader to the one belonging to this plugin.
*/
systemFunctionManager.setClassloader(getClass().getClassLoader());
return new FunctionLibrary(teiidVersion, systemFunctionManager.getSystemFunctions(),
functionTrees.values().toArray(new FunctionTree[0]));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@
@SuppressWarnings("nls")
public class RealMetadataFactory {

public static final SystemFunctionManager SFM = new SystemFunctionManager();
static {
SFM.setClassloader(RealMetadataFactory.class.getClassLoader());
}
public static final SystemFunctionManager SFM = new SystemFunctionManager(RealMetadataFactory.class.getClassLoader());

private static TransformationMetadata CACHED_EXAMPLE1 = example1();
private static TransformationMetadata CACHED_BQT = exampleBQT();
Expand Down Expand Up @@ -331,7 +328,7 @@ public static TransformationMetadata createTransformationMetadata(MetadataStore
for (Schema schema : metadataStore.getSchemas().values()) {
vdbMetaData.addModel(RealMetadataFactory.createModel(schema.getName(), schema.isPhysical()));
if (!schema.getFunctions().isEmpty()) {
udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values()), true));
udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values(), RealMetadataFactory.class.getClassLoader()), true));
}
}
return new TransformationMetadata(vdbMetaData, store, null, SFM.getSystemFunctions(), udfs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,7 @@ public void testVarArgs2() throws Exception {
sp.getParameter(1).getExpression());

sql = "call proc (1, (2, 3))"; //$NON-NLS-1$
sp = (StoredProcedure)helpResolve(sql, tm);
sp = (StoredProcedure)TestResolver.helpResolve(sql, tm);
assertEquals("EXEC proc(1, (2, 3))", sp.toString());
ArrayList<Expression> expressions = new ArrayList<Expression>();
expressions.add(new Constant(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,7 @@
@SuppressWarnings("nls")
public class RealMetadataFactory {

public static final SystemFunctionManager SFM = new SystemFunctionManager();
static {
SFM.setClassloader(RealMetadataFactory.class.getClassLoader());
}
public static final SystemFunctionManager SFM = new SystemFunctionManager(RealMetadataFactory.class.getClassLoader());

private static TransformationMetadata CACHED_EXAMPLE1 = example1();
private static TransformationMetadata CACHED_BQT = exampleBQT();
Expand Down Expand Up @@ -367,7 +364,7 @@ public static TransformationMetadata createTransformationMetadata(MetadataStore
for (Schema schema : metadataStore.getSchemas().values()) {
vdbMetaData.addModel(RealMetadataFactory.createModel(schema.getName(), schema.isPhysical()));
if (!schema.getFunctions().isEmpty()) {
udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values()), true));
udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values(), RealMetadataFactory.class.getClassLoader()), true));
}
}
TransformationMetadata metadata = new TransformationMetadata(vdbMetaData, store, null, SFM.getSystemFunctions(), udfs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ public class RealMetadataFactory {

public RealMetadataFactory(ITeiidServerVersion teiidVersion) {
this.teiidVersion = teiidVersion;
SFM = new SystemFunctionManager(teiidVersion);
SFM.setClassloader(getClass().getClassLoader());
SFM = new SystemFunctionManager(teiidVersion, getClass().getClassLoader());
parser = new QueryParser(teiidVersion);
}

Expand Down Expand Up @@ -413,8 +412,7 @@ public TransformationMetadata createTransformationMetadata(CompositeMetadataStor
for (Schema schema : store.getSchemas().values()) {
vdbMetaData.addModel(createModel(schema.getName(), schema.isPhysical()));
if (!schema.getFunctions().isEmpty()) {
UDFSource source = new UDFSource(schema.getFunctions().values());
source.setClassLoader(getClass().getClassLoader());
UDFSource source = new UDFSource(schema.getFunctions().values(), getClass().getClassLoader());
udfs.add(new FunctionTree(getTeiidVersion(), schema.getName(), source, true));
}
}
Expand Down

0 comments on commit a4b9da2

Please sign in to comment.