All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.platform.server.wls.WebLogic_10_Platform Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998, 2024 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     10/20/2008-1.1M4 Michael O'Brien
//       - 248748: Add WebLogic 10.3 specific JMX MBean attributes and functions
//       see http://wiki.eclipse.org/EclipseLink/DesignDocs/248748
//     11/06/2008-1.1M5 Michael O'Brien
//       - 248746: Add getModuleName() implementation and new getApplicationName()
//     05/07/2009-1.1.1 Dave Brosius
//       - 265755: [PATCH] Set application name correctly
//     06/30/2010-2.1.1 Michael O'Brien
//       - 316513: Enable JMX MBean functionality for JBoss, Glassfish and WebSphere in addition to WebLogic
//       Move JMX MBean generic registration code up from specific platforms
//       see http://wiki.eclipse.org/EclipseLink/DesignDocs/316513
//     10/18/2010-2.1.2 Michael O'Brien
//       - 328006: Refactor WebLogic MBeanServer registration to use active
//         WLS com.bea server when multiple instances returned
//       see http://wiki.eclipse.org/EclipseLink/DesignDocs/316513#DI_4:_20100624:_Verify_correct_MBeanServer_available_when_running_multiple_MBeanServer_Instances
//     01/01/2011-2.2 Michael O'Brien
//       - 333160: ModuleName string extraction code does not handle -1 not found index in 1 of 3 cases
//     07/21/2014-2.6.0 Lukas Jungmann
//       - 440018: Failed to find mbean server warning in the wls admin server log
package org.eclipse.persistence.platform.server.wls;

import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.JMXEnabledPlatform;
import org.eclipse.persistence.services.weblogic.MBeanWebLogicRuntimeServices;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.ExternalTransactionController;
import org.eclipse.persistence.transaction.wls.WebLogicTransactionController11;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.lang.reflect.Method;
import java.security.AccessController;

/**
 * PUBLIC:
 * 

* This is the concrete subclass responsible for representing WebLogic 10 specific behavior. * This includes WebLogic 10.3 behavior. */ public class WebLogic_10_Platform extends WebLogic_9_Platform implements JMXEnabledPlatform { // see http://docs.oracle.com/middleware/1213/wls/JMXCU/understandwls.htm#i1127767 /** This JNDI address is for JMX MBean registration */ private static final String JMX_JNDI_RUNTIME_REGISTER = "java:comp/env/jmx/runtime"; /* * If the cached MBeanServer is not used, then the unregister jndi address must be used to create a context * Note: the context must be explicitly closed after use or we may cache the user and get a * weblogic.management.NoAccessRuntimeException when trying to use the associated MBeanServer * see http://bugs.eclipse.org/238343 * see http://e-docs.bea.com/wls/docs100/jndi/jndi.html#wp467275 */ /** This JNDI address is for JMX MBean unregistration */ private static final String JMX_JNDI_RUNTIME_UNREGISTER = "java:comp/jmx/runtime"; /* * If the cached MBeanServer is not used, then the unregister jndi address must be used to create a context * Note: the context must be explicitly closed after use or we may cache the user and get a * weblogic.management.NoAccessRuntimeException when trying to use the associated MBeanServer * see http://bugs.eclipse.org/238343 * see http://e-docs.bea.com/wls/docs100/jndi/jndi.html#wp467275 */ /** This persistence.xml or sessions.xml property is used to override the moduleName */ protected static final String SERVER_SPECIFIC_MODULENAME_PROPERTY = "eclipselink.weblogic.moduleName"; /** This persistence.xml or sessions.xml property is used to override the applicationName */ protected static final String SERVER_SPECIFIC_APPLICATIONNAME_PROPERTY = "eclipselink.weblogic.applicationName"; /* * The following constants and attributes are used during reflective API calls */ /** Cache the WebLogic ThreadPoolRuntime for performance */ private ObjectName wlsThreadPoolRuntime = null; private static final String WLS_SERVICE_KEY = "com.bea:Name=RuntimeService,Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean"; private static final String WLS_SERVER_RUNTIME = "ServerRuntime"; private static final String WLS_THREADPOOL_RUNTIME = "ThreadPoolRuntime"; private static final String WLS_EXECUTE_THREAD_GET_METHOD_NAME = "getExecuteThread"; // see http://home.bea.com/internal/docs/wiki/p/view/jee/appinfothread private static final String WLS_APPLICATION_NAME_GET_METHOD_NAME = "getApplicationName"; private static final String WLS_MODULE_NAME_GET_METHOD_NAME = "getModuleName"; /** Search String in WebLogic ClassLoader for the application:persistence_unit name */ private static final String WLS_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX = "annotation: "; static { /* Override by subclass: Search String in application server ClassLoader for the application:persistence_unit name */ APP_SERVER_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX = "/deploy/"; /* Override by subclass: Search String in application server session for ejb modules */ APP_SERVER_CLASSLOADER_MODULE_EJB_SEARCH_STRING_PREFIX = ".jar/"; /* Override by subclass: Search String in application server session for war modules */ APP_SERVER_CLASSLOADER_MODULE_WAR_SEARCH_STRING_PREFIX = ".war/"; APP_SERVER_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_POSTFIX = "postfix,match~not;required^"; APP_SERVER_CLASSLOADER_MODULE_EJB_WAR_SEARCH_STRING_POSTFIX = "postfix,match~not;required^"; } /** * INTERNAL: * Default Constructor: All behavior for the default constructor is inherited */ public WebLogic_10_Platform(DatabaseSession newDatabaseSession) { super(newDatabaseSession); this.enableRuntimeServices(); // Create the JMX MBean specific to this platform for later registration this.prepareServerSpecificServicesMBean(); } @Override public boolean isRuntimeServicesEnabledDefault() { return true; } /** * INTERNAL: * prepareServerSpecificServicesMBean(): Server specific implementation of the * creation and deployment of the JMX MBean to provide runtime services for the * databaseSession. *

* Default is to do nothing. * Implementing platform classes must override this function and supply * the server specific MBean instance for later registration by calling it in the constructor. * * @see #isRuntimeServicesEnabled() * @see #disableRuntimeServices() * @see #registerMBean() */ @Override public void prepareServerSpecificServicesMBean() { // No check for an existing cached MBean - we will replace it if it exists if(getDatabaseSession() != null && shouldRegisterRuntimeBean) { this.setRuntimeServicesMBean(new MBeanWebLogicRuntimeServices(getDatabaseSession())); } } /** * INTERNAL: * serverSpecificRegisterMBean(): Server specific implementation of the * creation and deployment of the JMX MBean to provide runtime services for my * databaseSession. * * @see #isRuntimeServicesEnabled() * @see #disableRuntimeServices() * @see #registerMBean() */ @Override public void serverSpecificRegisterMBean() { super.serverSpecificRegisterMBean(); // get and cache module and application name during registration initializeApplicationNameAndModuleName(); } /** * INTERNAL: * Return the MBeanServer to be used for MBean registration and deregistration.
* This MBeanServer reference is lazy loaded and cached on the platform.
* There are multiple ways of getting the MBeanServer
*

* 1) MBeanServerFactory static function - working for 3 of 4 servers WebSphere, JBoss and Glassfish in a generic way
* - JBoss returns 2 MBeanServers in the List - but one of them has a null domain - we don't use that one
* - WebLogic may return 2 MBeanServers - in that case we want to register with the one containing the "com.bea" tree * 2) ManagementFactory static function - what is the difference in using this one over the one returning a List of servers
* 3) JNDI lookup
* 4) Direct server specific native API

* We are using method (3)
* * @return the JMX specification MBeanServer */ @Override public MBeanServer getMBeanServer() { //super.getMBeanServer(); keep commented except for generic registration testing // 328006: This function overrides the generic version used for WebSphere, JBoss and Glassfish // Get a possible cached MBeanServer from the superclass first if(null == mBeanServer) { Context initialContext = null; try { initialContext = new InitialContext(); try { // mBeanServer = (MBeanServer) initialContext.lookup(JMX_JNDI_RUNTIME_REGISTER); if (null == mBeanServer) { getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "failed_to_find_mbean_server", "null returned from JNDI lookup of " + JMX_JNDI_RUNTIME_REGISTER); } } catch (NamingException ne1) { //#440018 Fallback for the case when the JMX client classes are not located in a Java EE module mBeanServer = (MBeanServer) initialContext.lookup(JMX_JNDI_RUNTIME_UNREGISTER); if (null == mBeanServer) { getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "failed_to_find_mbean_server", "null returned from JNDI lookup of " + JMX_JNDI_RUNTIME_UNREGISTER); } } if (mBeanServer != null) { // Verify that this is a weblogic.management.jmx.mbeanserver.WLSMBeanServer if(!mBeanServer.toString().contains("WLSMBeanServer")) { // MBeanServer is not a WebLogic type - likely a com.sun.jmx.mbeanserver.JmxMBeanServer getAbstractSession().log(SessionLog.FINEST, SessionLog.SERVER, "sequencing_connected", null); } getAbstractSession().log(SessionLog.FINER, SessionLog.SERVER, "jmx_mbean_runtime_services_registration_mbeanserver_print", new Object[]{mBeanServer, mBeanServer.getMBeanCount(), mBeanServer.getDefaultDomain(), 0}); } } catch (NamingException ne) { getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "failed_to_find_mbean_server", ne); } catch (Exception exception) { getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "problem_registering_mbean", exception); } finally { // close the context // see http://forums.bea.com/thread.jspa?threadID=600004445 // see http://e-docs.bea.com/wls/docs81/jndi/jndi.html#471919 // see http://e-docs.bea.com/wls/docs100/jndi/jndi.html#wp467275 try { if(null != initialContext) { initialContext.close(); } } catch (NamingException ne) { // exceptions on context close will be ignored, the context will be GC'd } } } return mBeanServer; } /** * INTERNAL: * Get the applicationName and moduleName from the runtime WebLogic MBean reflectively * @deprecated */ @Override @Deprecated protected void initializeApplicationNameAndModuleName() { // use non-reflective superclass method that searches the database session and classLoader strings // to be DEPRECATED // Get property from persistence.xml or sessions.xml String jpaModuleName = (String)getDatabaseSession().getProperty(SERVER_SPECIFIC_MODULENAME_PROPERTY); String jpaApplicationName = (String)getDatabaseSession().getProperty(SERVER_SPECIFIC_APPLICATIONNAME_PROPERTY); if (jpaModuleName != null) { setModuleName(jpaModuleName); } else { jpaModuleName = getModuleOrApplicationName(WLS_MODULE_NAME_GET_METHOD_NAME); // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader if(null != jpaModuleName && jpaModuleName.indexOf('@') != -1) { setModuleName(jpaModuleName.substring(jpaModuleName.indexOf('@') + 1)); } else { setModuleName(jpaModuleName); } } if (jpaApplicationName != null) { setApplicationName(jpaApplicationName); } else { jpaApplicationName = getModuleOrApplicationName(WLS_APPLICATION_NAME_GET_METHOD_NAME); // defer to the superclass implementation if(null == jpaApplicationName) { jpaApplicationName = super.getApplicationName(); } // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader if(null != jpaApplicationName && jpaApplicationName.indexOf('@') > -1) { setApplicationName(jpaApplicationName.substring(jpaApplicationName.indexOf('@') + 1)); } else { setApplicationName(jpaApplicationName); } } // TODO: remove: Final check for null values if(null == getApplicationName()) { setApplicationName(DEFAULT_SERVER_NAME_AND_VERSION); } if(null == getModuleName()) { setModuleName(DEFAULT_SERVER_NAME_AND_VERSION); } getAbstractSession().log(SessionLog.FINEST, SessionLog.SERVER, "mbean_get_application_name", getDatabaseSession().getName(), getApplicationName()); getAbstractSession().log(SessionLog.FINEST, SessionLog.SERVER, "mbean_get_module_name", getDatabaseSession().getName(), getModuleName()); } /** * INTERNAL: * This method will return the application|module name for WebLogic. * If the call to executeThread on the MBean fails - return the current classloader * Thread.currentThread().getContextClassLoader() *

* ER 248746: Use reflection to obtain the application name (EJB, Web or MDB module) * Get either a String containing the module/applicationName or a WebLogic classLoader that contains the module/applicationName in the format... * weblogic.utils.classloaders.ChangeAwareClassLoader@19bb43f finder: weblogic.utils.classloaders.CodeGenClassFinder@ab7c2e annotation: org.eclipse.persistence.example.jpa.server.weblogic.enterpriseEAR@enterprise * If the getExecuteThread call failed, use the classloader string representation as backup. * If the classloader is not in the correct format, defer to superclass. * * @return String module|application Name from WLS */ private String getModuleOrApplicationName(String getMethodName) { Object classLoaderOrString = null;//this.getDatabaseSession().getPlatform().getConversionManager().getLoader(); Object executeThread = getExecuteThreadFromMBean(); if (executeThread != null) { try { // perform a reflective public java.lang.String // weblogic.work.ExecuteThreadRuntime. Method getMethod = PrivilegedAccessHelper.getPublicMethod(executeThread.getClass(), getMethodName, new Class[] {}, false); if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { classLoaderOrString = AccessController.doPrivileged(new PrivilegedMethodInvoker<>(getMethod, executeThread, null)); } else { classLoaderOrString = PrivilegedAccessHelper.invokeMethod(getMethod, executeThread); } if(classLoaderOrString instanceof ClassLoader) { // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader String jpaModuleNameRoot = classLoaderOrString.toString(); if(null != jpaModuleNameRoot) { int startIndex = jpaModuleNameRoot.indexOf( WLS_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX); if(startIndex > -1) { classLoaderOrString = jpaModuleNameRoot.substring(startIndex + WLS_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX.length()); } } } } catch (Exception ex) { // catch all Illegal*Exception and PrivilegedActionException /* * If the reflective call to ExecuteThreadRuntime failed for * this an older version of WebLogic 10.3 failed, use the * classloader as a backup method */ getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "problem_with_reflective_weblogic_call_mbean", ex, getMethodName); } } return (String)classLoaderOrString; } /** * INTERNAL: * This convenience method will look up a WebLogic execute thread from the runtime * MBean tree. The execute thread contains application information. This code * will use the name of the current thread to lookup the corresponding ExecuteThread. * The ExecuteThread will allow us to obtain the application name (and version, etc). *

* Note that the MBeanServer and ThreadPoolRuntime instances will be cached for * performance. * * @return application name or null if the name cannot be obtained */ private Object getExecuteThreadFromMBean() { // Initialize the threadPoolRuntime and get the executeThreadRuntime //this.getDatabaseSession().getPlatform().getConversionManager().getLoader(); if (getMBeanServer() != null) { // Lazy load the ThreadPoolRuntime instance if (wlsThreadPoolRuntime == null) { try { ObjectName service = new ObjectName(WLS_SERVICE_KEY); ObjectName serverRuntime = (ObjectName) getMBeanServer().getAttribute(service, WLS_SERVER_RUNTIME); wlsThreadPoolRuntime = (ObjectName) getMBeanServer().getAttribute(serverRuntime, WLS_THREADPOOL_RUNTIME); } catch (Exception ex) { getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "jmx_mbean_runtime_services_threadpool_initialize_failed", ex); } } // Get the executeThreadRuntimeObject if (wlsThreadPoolRuntime != null) { try { // Perform a reflective getExecuteThread() return getMBeanServer().invoke(wlsThreadPoolRuntime, WLS_EXECUTE_THREAD_GET_METHOD_NAME, new Object[] { Thread.currentThread().getName() }, new String[] { String.class.getName() }); } catch (Exception ex) { /* * If the reflective call to get the executeThreadRuntime object failed on the MBean because * this an older version of WebLogic 10.3, continue and use the classloader as a backup method */ getAbstractSession().log(SessionLog.WARNING, SessionLog.SERVER, "jmx_mbean_runtime_services_get_executethreadruntime_object_failed", ex); } } } return null; } /** * Return the method for the WebLogic JDBC connection wrapper vendorConnection. * WLS 10.3.4.0 added a getVendorConnectionSafe that does not invalidate the connection, * so use this if available. */ @Override protected Method getVendorConnectionMethod() { if ((this.vendorConnectionMethod == null) && (!getWebLogicConnectionClass().equals(void.class))) { try { this.vendorConnectionMethod = PrivilegedAccessHelper.getDeclaredMethod(getWebLogicConnectionClass(), "getVendorConnectionSafe", new Class[0]); } catch (NoSuchMethodException not1034) { try { this.vendorConnectionMethod = PrivilegedAccessHelper.getDeclaredMethod(getWebLogicConnectionClass(), "getVendorConnection", new Class[0]); } catch (NoSuchMethodException exception) { getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception); } } } return this.vendorConnectionMethod; } /** * INTERNAL: * Check whether JTA 1.1 API is available. * WLS 10.0 and later is JTA 1.1 compliant. * * @return always returns {@code true} for WLS 10.0 and later. */ @Override public boolean isJTA11() { return true; } /** * INTERNAL: getExternalTransactionControllerClass(): Answer the class of * external transaction controller to use for WebLogic. This is read-only. * * @return Class externalTransactionControllerClass * * @see org.eclipse.persistence.transaction.JTA11TransactionController * @see org.eclipse.persistence.platform.server.ServerPlatformBase#isJTAEnabled() * @see org.eclipse.persistence.platform.server.ServerPlatformBase#disableJTA() * @see org.eclipse.persistence.platform.server.ServerPlatformBase#initializeExternalTransactionController() */ @Override public Class getExternalTransactionControllerClass() { if (externalTransactionControllerClass == null) { externalTransactionControllerClass = WebLogicTransactionController11.class; } return externalTransactionControllerClass; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy