Skip to content

OPENJPA-2632 use TCCL as fallback #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ public interface OpenJPAConfiguration
public static final String OPTION_POSTLOAD_ON_MERGE =
"openjpa.option.PostLoadOnMerge";

/**
* Option to enable TCCL if the result class for select new is not found
* in the entities classloader
*/
public static final String OPTION_USE_TCCL_IN_SELECT_NEW =
"openjpa.option.UseTCCLinSelectNew";

/**
* Return the set of option strings supported by this runtime. This set
* is mutable.
Expand Down Expand Up @@ -1949,5 +1956,32 @@ public interface OpenJPAConfiguration
* @since 2.2.0
*/
public void setOptimizeIdCopy(Boolean optimizeIds);

/**
* Indicates if the {@link Thread#contextClassLoader} should be used
* as fallback if the result class for {@code select new} is not found
* by the classloader of the entity.
*
* @since 2.4.2
*/
public boolean getUseTCCLinSelectNew();

/**
* Indicates if the {@link Thread#contextClassLoader} should be used
* as fallback if the result class for {@code select new} is not found
* by the classloader of the entity.
*
* @since 2.4.2
*/
public void setUseTCCLinSelectNew(boolean useTcclForSelectNew);

/**
* Indicates if the {@link Thread#contextClassLoader} should be used
* as fallback if the result class for {@code select new} is not found
* by the classloader of the entity.
*
* @since 2.4.2
*/
public void setUseTCCLinSelectNew(Boolean useTcclForSelectNew);
}

Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ public class OpenJPAConfigurationImpl
public PluginListValue instrumentationProviders;
public BooleanValue postLoadOnMerge;
public BooleanValue optimizeIdCopy;
public BooleanValue useTcclForSelectNew;

// custom values
public BrokerFactoryValue brokerFactoryPlugin;
Expand Down Expand Up @@ -604,6 +605,10 @@ public OpenJPAConfigurationImpl(boolean derivations, boolean loadGlobals) {
aliases = new String[] { "default", AuditLogger.class.getName(), };
auditorPlugin.setAliases(aliases);
auditorPlugin.setInstantiatingGetter("getAuditorInstance");

useTcclForSelectNew = addBoolean("UseTCCLinSelectNew");
useTcclForSelectNew.setDefault("false");
useTcclForSelectNew.set(false);

// initialize supported options that some runtimes may not support
supportedOptions.add(OPTION_NONTRANS_READ);
Expand All @@ -622,6 +627,7 @@ public OpenJPAConfigurationImpl(boolean derivations, boolean loadGlobals) {
supportedOptions.add(OPTION_VALUE_INCREMENT);
supportedOptions.add(OPTION_DATASTORE_CONNECTION);
supportedOptions.add(OPTION_POSTLOAD_ON_MERGE);
supportedOptions.add(OPTION_USE_TCCL_IN_SELECT_NEW);

if (derivations)
ProductDerivations.beforeConfigurationLoad(this);
Expand Down Expand Up @@ -1873,5 +1879,22 @@ public void setOptimizeIdCopy(Boolean optimizeId) {
setOptimizeIdCopy(optimizeId.booleanValue());
}
}

@Override
public boolean getUseTCCLinSelectNew() {
return useTcclForSelectNew.get();
}

@Override
public void setUseTCCLinSelectNew(boolean useTcclForSelectNew) {
this.useTcclForSelectNew.set(useTcclForSelectNew);
}

@Override
public void setUseTCCLinSelectNew(Boolean useTcclForSelectNew) {
if (useTcclForSelectNew != null) {
setUseTCCLinSelectNew(useTcclForSelectNew.booleanValue());
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -1692,7 +1692,7 @@ else if (importName.endsWith(".*")) {
private Class toClass(String name) {
if (_loader == null)
_loader = _broker.getConfiguration().getClassResolverInstance().
getClassLoader(_class, _broker.getClassLoader());
getClassLoader(_class, _broker.getClassLoader());
try {
return Strings.toClass(name, _loader);
} catch (RuntimeException re) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.Serializable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.security.AccessController;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
Expand Down Expand Up @@ -56,6 +57,7 @@
import org.apache.openjpa.kernel.exps.Subquery;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.OrderedMap;
import org.apache.openjpa.lib.util.Localizer.Message;
Expand Down Expand Up @@ -410,6 +412,22 @@ private void evalProjectionsResultShape(JPQLNode selectionsNode,
String baseName = left(node).getChild(n-1).text;
constructor = resolver.classForName(baseName, null);
}

if (constructor == null && resolver.getConfiguration().getUseTCCLinSelectNew()) {
try {
if (System.getSecurityManager() == null) {
constructor = AccessController.doPrivileged(
J2DoPrivHelper.getForNameAction(resultClassName, false,
AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction())));
}
else {
constructor = Thread.currentThread().getContextClassLoader().loadClass(resultClassName);
}
} catch (Exception e) {
// ignore
}
}

if (constructor == null)
throw parseException(EX_USER, "no-constructor",
new Object[]{ resultClassName }, null);
Expand Down