blob: 1efb58be9039e3c5cac45a8144a33374c71d3373 [file] [log] [blame]
/*
* Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.ejb.portable;
import java.util.Properties;
import java.io.FileInputStream;
import java.io.IOException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import jakarta.ejb.spi.HandleDelegate;
/**
* Common code for looking up the java:comp/HandleDelegate.
*
* This class can potentially be instantiated in another vendor's container so it must not refer to any non-portable
* RI-specific classes.
*
* @author Kenneth Saks
*/
public class HandleDelegateUtil {
private static final String JNDI_PROPERTY_FILE_NAME = "com.sun.ejb.portable.jndi.propertyfilename";
// Class-level state for jndi properties override. Flag is used
// so that we only check once for jndi properties file override.
private static boolean checkedJndiProperties;
// contents of file referred to by jndi properties override
private static Properties jndiProperties;
private static volatile HandleDelegate _cachedHandleDelegate;
static HandleDelegate getHandleDelegate() throws NamingException {
if (_cachedHandleDelegate == null) {
synchronized (HandleDelegateUtil.class) {
if (_cachedHandleDelegate == null) {
_cachedHandleDelegate = createHandleDelegate();
}
}
}
return _cachedHandleDelegate;
}
private static HandleDelegate createHandleDelegate() throws NamingException {
HandleDelegate handleDelegate;
try {
InitialContext ctx = new InitialContext();
handleDelegate = (HandleDelegate) ctx.lookup("java:comp/HandleDelegate");
} catch (NamingException ne) {
// If the lookup fails, it's probably because the default
// InitialContext settings needed to access the correct
// java:comp/HandleDelegate have been overridden in this VM.
// In that case, check if the system value class override
// property file is available and if so use it.
Properties props = null;
try {
props = getJndiProperties();
} catch (Exception e) {
// Exception while attempting to access jndi property override.
// Create new NamingException that describes the error.
NamingException ne2 = new NamingException("Error while accessing " + JNDI_PROPERTY_FILE_NAME + " : " + e.getMessage());
ne2.initCause(e);
throw ne2;
}
if (props == null) {
// There was no property override set.
NamingException ne3 = new NamingException("java:comp/HandleDelegate not found. Unable to "
+ " use jndi property file override since " + JNDI_PROPERTY_FILE_NAME + " has NOT been set");
ne3.initCause(ne);
throw ne3;
}
try {
InitialContext ctx = new InitialContext(props);
handleDelegate = (HandleDelegate) ctx.lookup("java:comp/HandleDelegate");
} catch (NamingException ne4) {
NamingException overrideEx = new NamingException(
"Unable to lookup HandleDelegate " + "with override properties = " + props.toString());
overrideEx.initCause(ne4);
throw overrideEx;
}
}
return handleDelegate;
}
/**
* Internal method for accessing jndi properties override. We only look for properties file at most once, whether it is
* present or not.
*
*/
private static Properties getJndiProperties() throws Exception {
synchronized (HandleDelegateUtil.class) {
if (!checkedJndiProperties) {
FileInputStream fis = null;
try {
String jndiPropertyFileName = System.getProperty(JNDI_PROPERTY_FILE_NAME);
if (jndiPropertyFileName != null) {
fis = new FileInputStream(jndiPropertyFileName);
jndiProperties = new Properties();
jndiProperties.load(fis);
// Let an exception encountered here bubble up, so
// we can include its info in the exception propagated
// to the application.
}
} finally {
// Always set to true so we don't keep doing this
// system property and file access multiple times
checkedJndiProperties = true;
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// ignore
}
}
}
}
}
return jndiProperties;
}
}