21.5. Acesso Remoto a Serviços, Invocadores Desanexados
21.5. Acesso Remoto a Serviços, Invocadores Desanexados
Adicionado à noção dos serviços MBean que permitem a habilidade de integrar a funcionalidade arbitrária, o JBoss também possui um conceito invocador desanexado que permite que os serviços MBean exponham interfaces funcionais através de protocolos arbitrários para o acesso remoto por clientes. A noção de um invocador desanexado é que o remoting e o protocolo pelo qual um serviço é acessado é um aspecto funcional ou serviço independente do componente. Portanto, você pode tornar disponível um serviço de nomeação para uso através do RMI/JRMP, RMI/HTTP, RMI/SOAP, ou qualquer outro transporte personalizado arbitrário.
Figura 21.1. Os componentes principais da arquitetura do invocador desanexada
Ao lado do cliente, existe um cliente proxy que expõe a(s) interface(s) do serviço MBean. Este é o mesmo proxy dinâmico de menor compilação que é usado para o EJB principal e interfaces remotas. A única diferença entre um proxy para o serviço arbritário e o EJB é o conjunto de interfaces expostas como também os interceptores encontrados dentro do proxy. Os interceptores do cliente são representados pelos retângulos encontrados dentro do proxy do cliente. Um interceptor é um tipo de linha de montagem do padrão que permite a transformação de uma invocação de método e/ou valores de retorno. Um cliente obtém um proxy através de alguns mecanismos de busca, tipicamente o JNDI. Embora o RMI esteja indicado na Figura 21.1, “Os componentes principais da arquitetura do invocador desanexada”, a única solicitação real da interface exposta é que eles sejam serializados entre o servidor do cliente sobre o JNDI assim como a camada de transporte.
A escolha da camada de transporte é determinada pelo último interceptor no proxy do cliente, que é referenciado como um Interceptor do Invocador na Figura 21.1, “Os componentes principais da arquitetura do invocador desanexada”. O interceptor do invocador contém uma referência ao stub específico de transporte ao lado do servidor do serviço MBean do Invocador Desanexado. O interceptor do invocador também manuseia a otimização das chamadas que ocorrem com o mesmo VM como um MBean de destino. Quando o interceptor do invocador detecta que é esta a situação, a chamada é passada a um invocador de referência por chamada, que simplesmente passa a invocação através do MBean de destino.
O serviço do invocador desanexado é responsável por disponibilizar a operação de invocação genérica através do transporte que o invocador desanexado manuseia. A interface Invoker ilustra a operação de invocação genérica.
package org.jboss.invocation;
import java.rmi.Remote;
import org.jboss.proxy.Interceptor;
import org.jboss.util.id.GUID;
public interface Invoker
extends Remote
{
GUID ID = new GUID();
String getServerHostName() throws Exception;
Object invoke(Invocation invocation) throws Exception;
}
package org.jboss.invocation;
import java.rmi.Remote;
import org.jboss.proxy.Interceptor;
import org.jboss.util.id.GUID;
public interface Invoker
extends Remote
{
GUID ID = new GUID();
String getServerHostName() throws Exception;
Object invoke(Invocation invocation) throws Exception;
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
A interface do Invocador estende o Remote para ser compatível com o RMI, mas não significa que um invocador deve expor um stub de serviço RMI. O serviço invocador desanexado age como um transporte de fuga que aceita invocações representadas como um objeto org.jboss.invocation.Invocation sobre o transporte específico. O serviço invocador desempacota a invocação e a envia à destinação do serviço MBean representado pelo MBean de Destino na Figura 21.1, “Os componentes principais da arquitetura do invocador desanexada”. Além disso, ele empacota o valor de retorno ou exceção resultante do retorno de chamada enviado ao cliente.
O objeto Invocation é apenas uma representação do contexto da invocação do método. Ele inclui o nome do MBean de destino, o método, os argumentos do método, um contexto de informação associada com o proxy pela fábrica do proxy e um mapa arbitrário de dados associados com a invocação pelos interceptores do proxy do cliente.
Definição de uma operação JMX coincidente com a assinatura: public Object invoke(org.jboss.invocation.Invocation) throws Exception.
Criação de um mapeamento HashMap<Long, Method> a partir dos java.lang.reflect.Methods de interface exibidos à representação hash longa usando o método org.jboss.invocation.MarshalledInvocation.calculateHash.
Implementa a operação JMX invoke(Invocation) e usa o mapeamento hash da interface para transformar a longa representação hash do método invocado para o java.lang.reflect.Method da interface exposta. A reflexão é usada para executar a invocação atual no objeto associado com o serviço MBean que atualiza a interface exposta.
Copiar o linkLink copiado para a área de transferência!
Esta seção apresenta o org.jboss.jmx.connector.invoker.InvokerAdaptorService e sua configuração de acesso através do RMI/JRMP como uma amostra dos passos solicitados para fornecimento de acesso remoto a um serviço MBean.
Exemplo 21.1. O InvokerAdaptorService MBean
O InvokerAdaptorService é um serviço MBean simples que existe para preenchimento da função do MBean de destino no invocador padrão desanexado.
package org.jboss.jmx.connector.invoker;
public interface InvokerAdaptorServiceMBean
extends org.jboss.system.ServiceMBean
{
Class getExportedInterface();
void setExportedInterface(Class exportedInterface);
Object invoke(org.jboss.invocation.Invocation invocation)
throws Exception;
}
package org.jboss.jmx.connector.invoker;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.mx.server.ServerConstants;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.Registry;
public class InvokerAdaptorService
extends ServiceMBeanSupport
implements InvokerAdaptorServiceMBean, ServerConstants
{
private static ObjectName mbeanRegistry;
static {
try {
mbeanRegistry = new ObjectName(MBEAN_REGISTRY);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
private Map marshalledInvocationMapping = new HashMap();
private Class exportedInterface;
public Class getExportedInterface()
{
return exportedInterface;
}
public void setExportedInterface(Class exportedInterface)
{
this.exportedInterface = exportedInterface;
}
protected void startService()
throws Exception
{
// Build the interface method map
Method[] methods = exportedInterface.getMethods();
HashMap tmpMap = new HashMap(methods.length);
for (int m = 0; m < methods.length; m ++) {
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
// Place our ObjectName hash into the Registry so invokers can
// resolve it
Registry.bind(new Integer(serviceName.hashCode()), serviceName);
}
protected void stopService()
throws Exception
{
Registry.unbind(new Integer(serviceName.hashCode()));
}
public Object invoke(Invocation invocation)
throws Exception
{
// Make sure we have the correct classloader before unmarshalling
Thread thread = Thread.currentThread();
ClassLoader oldCL = thread.getContextClassLoader();
// Get the MBean this operation applies to
ClassLoader newCL = null;
ObjectName objectName = (ObjectName)
invocation.getValue("JMX_OBJECT_NAME");
if (objectName != null) {
// Obtain the ClassLoader associated with the MBean deployment
newCL = (ClassLoader)
server.invoke(mbeanRegistry, "getValue",
new Object[] { objectName, CLASSLOADER },
new String[] { ObjectName.class.getName(),
"java.lang.String" });
}
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(newCL);
}
try {
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation) {
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
// Invoke the MBeanServer method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try {
String name = method.getName();
Class[] sig = method.getParameterTypes();
Method mbeanServerMethod =
MBeanServer.class.getMethod(name, sig);
value = mbeanServerMethod.invoke(server, args);
} catch(InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw (Exception) t;
} else {
throw new UndeclaredThrowableException(t, method.toString());
}
}
return value;
} finally {
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(oldCL);
}
}
}
}
package org.jboss.jmx.connector.invoker;
public interface InvokerAdaptorServiceMBean
extends org.jboss.system.ServiceMBean
{
Class getExportedInterface();
void setExportedInterface(Class exportedInterface);
Object invoke(org.jboss.invocation.Invocation invocation)
throws Exception;
}
package org.jboss.jmx.connector.invoker;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.mx.server.ServerConstants;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.Registry;
public class InvokerAdaptorService
extends ServiceMBeanSupport
implements InvokerAdaptorServiceMBean, ServerConstants
{
private static ObjectName mbeanRegistry;
static {
try {
mbeanRegistry = new ObjectName(MBEAN_REGISTRY);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
private Map marshalledInvocationMapping = new HashMap();
private Class exportedInterface;
public Class getExportedInterface()
{
return exportedInterface;
}
public void setExportedInterface(Class exportedInterface)
{
this.exportedInterface = exportedInterface;
}
protected void startService()
throws Exception
{
// Build the interface method map
Method[] methods = exportedInterface.getMethods();
HashMap tmpMap = new HashMap(methods.length);
for (int m = 0; m < methods.length; m ++) {
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
// Place our ObjectName hash into the Registry so invokers can
// resolve it
Registry.bind(new Integer(serviceName.hashCode()), serviceName);
}
protected void stopService()
throws Exception
{
Registry.unbind(new Integer(serviceName.hashCode()));
}
public Object invoke(Invocation invocation)
throws Exception
{
// Make sure we have the correct classloader before unmarshalling
Thread thread = Thread.currentThread();
ClassLoader oldCL = thread.getContextClassLoader();
// Get the MBean this operation applies to
ClassLoader newCL = null;
ObjectName objectName = (ObjectName)
invocation.getValue("JMX_OBJECT_NAME");
if (objectName != null) {
// Obtain the ClassLoader associated with the MBean deployment
newCL = (ClassLoader)
server.invoke(mbeanRegistry, "getValue",
new Object[] { objectName, CLASSLOADER },
new String[] { ObjectName.class.getName(),
"java.lang.String" });
}
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(newCL);
}
try {
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation) {
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
// Invoke the MBeanServer method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try {
String name = method.getName();
Class[] sig = method.getParameterTypes();
Method mbeanServerMethod =
MBeanServer.class.getMethod(name, sig);
value = mbeanServerMethod.invoke(server, args);
} catch(InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw (Exception) t;
} else {
throw new UndeclaredThrowableException(t, method.toString());
}
}
return value;
} finally {
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(oldCL);
}
}
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
O código foi separado em blocos lógicos, com comentários explicativos de como cada bloco opera, com o objetivo de ajudar a entender o InvokerAdaptorServiceMBean.
Exemplo 21.2. Bloco Um
package org.jboss.jmx.connector.invoker;
public interface InvokerAdaptorServiceMBean
extends org.jboss.system.ServiceMBean
{
Class getExportedInterface();
void setExportedInterface(Class exportedInterface);
Object invoke(org.jboss.invocation.Invocation invocation)
throws Exception;
}
package org.jboss.jmx.connector.invoker;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.mx.server.ServerConstants;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.Registry;
public class InvokerAdaptorService
extends ServiceMBeanSupport
implements InvokerAdaptorServiceMBean, ServerConstants
{
private static ObjectName mbeanRegistry;
static {
try {
mbeanRegistry = new ObjectName(MBEAN_REGISTRY);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
private Map marshalledInvocationMapping = new HashMap();
private Class exportedInterface;
public Class getExportedInterface()
{
return exportedInterface;
}
public void setExportedInterface(Class exportedInterface)
{
this.exportedInterface = exportedInterface;
}
...
package org.jboss.jmx.connector.invoker;
public interface InvokerAdaptorServiceMBean
extends org.jboss.system.ServiceMBean
{
Class getExportedInterface();
void setExportedInterface(Class exportedInterface);
Object invoke(org.jboss.invocation.Invocation invocation)
throws Exception;
}
package org.jboss.jmx.connector.invoker;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.mx.server.ServerConstants;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.Registry;
public class InvokerAdaptorService
extends ServiceMBeanSupport
implements InvokerAdaptorServiceMBean, ServerConstants
{
private static ObjectName mbeanRegistry;
static {
try {
mbeanRegistry = new ObjectName(MBEAN_REGISTRY);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
private Map marshalledInvocationMapping = new HashMap();
private Class exportedInterface;
public Class getExportedInterface()
{
return exportedInterface;
}
public void setExportedInterface(Class exportedInterface)
{
this.exportedInterface = exportedInterface;
}
...
Copy to ClipboardCopied!Toggle word wrapToggle overflow
A interface do MBean Padrão InvokerAdaptorServiceMBean do InvokerAdaptorService possui um atributo ExportedInterface único e uma operação invoke(Invocation) única.
ExportedInterface
O atributo permite personalização do tipo de interface que o serviço expõe aos clientes. Ela deve ser compatível à classe MBeanServer no que se diz respeito ao nome e assinatura do método.
invoke(Invocation)
A operação é o ponto de entrada solicitado que os serviços MBean devem expor para participar do padrão do invocador desanexado. Esta operação é invocada pelos serviços do invocador desanexado que foram configurados para fornecer acesso ao InvokerAdaptorService.
Exemplo 21.3. Bloco Dois
protected void startService()
throws Exception
{
// Build the interface method map
Method[] methods = exportedInterface.getMethods();
HashMap tmpMap = new HashMap(methods.length);
for (int m = 0; m < methods.length; m ++) {
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
// Place our ObjectName hash into the Registry so invokers can
// resolve it
Registry.bind(new Integer(serviceName.hashCode()), serviceName);
}
protected void stopService()
throws Exception
{
Registry.unbind(new Integer(serviceName.hashCode()));
}
protected void startService()
throws Exception
{
// Build the interface method map
Method[] methods = exportedInterface.getMethods();
HashMap tmpMap = new HashMap(methods.length);
for (int m = 0; m < methods.length; m ++) {
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
// Place our ObjectName hash into the Registry so invokers can
// resolve it
Registry.bind(new Integer(serviceName.hashCode()), serviceName);
}
protected void stopService()
throws Exception
{
Registry.unbind(new Integer(serviceName.hashCode()));
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Este bloco de código possui o HashMap<Long, Method> da Classe exportedInterface usando o método de utilidade org.jboss.invocation.MarshalledInvocation.calculateHash(Method).
Devido às instâncias java.lang.reflect.Method não serem serializadas, uma versão MarshalledInvocation da classe Invocation é usada para empacotar a invocação entre o cliente e o servidor. O MarshalledInvocation substitui as instâncias de Método pela sua representação hash correspondente. Ao lado do servidor, o MarshalledInvocation deve ser informado qual é o hash para o mapeamento do Método.
Este bloco de código cria um mapeamento entre o nome do serviço InvokerAdaptorService e sua representação de código hash. Isto é usado pelos invocadores desanexados para determinar qual é o ObjectName para o Invocation.
Quando o nome MBean é armazenado no Invocation, seu armazenamento assim como seu hashCode uma vez que os ObjectNames são objetos relativamente caros para criação. O org.jboss.system.Registry é um mapa global como a construção que os invocadores usam para armazenar o código hash para mapeamentos do ObjectName.
Exemplo 21.4. Bloco Três
public Object invoke(Invocation invocation)
throws Exception
{
// Make sure we have the correct classloader before unmarshalling
Thread thread = Thread.currentThread();
ClassLoader oldCL = thread.getContextClassLoader();
// Get the MBean this operation applies to
ClassLoader newCL = null;
ObjectName objectName = (ObjectName)
invocation.getValue("JMX_OBJECT_NAME");
if (objectName != null) {
// Obtain the ClassLoader associated with the MBean deployment
newCL = (ClassLoader)
server.invoke(mbeanRegistry, "getValue",
new Object[] { objectName, CLASSLOADER },
new String[] { ObjectName.class.getName(),
"java.lang.String" });
}
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(newCL);
}
public Object invoke(Invocation invocation)
throws Exception
{
// Make sure we have the correct classloader before unmarshalling
Thread thread = Thread.currentThread();
ClassLoader oldCL = thread.getContextClassLoader();
// Get the MBean this operation applies to
ClassLoader newCL = null;
ObjectName objectName = (ObjectName)
invocation.getValue("JMX_OBJECT_NAME");
if (objectName != null) {
// Obtain the ClassLoader associated with the MBean deployment
newCL = (ClassLoader)
server.invoke(mbeanRegistry, "getValue",
new Object[] { objectName, CLASSLOADER },
new String[] { ObjectName.class.getName(),
"java.lang.String" });
}
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(newCL);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Este código de bloco obtém o nome do MBean que a operação MBeanServer executou e busca o carregador de classe associado com a implementação SAR do MBean. Esta informação encontra-se disponível através do org.jboss.mx.server.registry.BasicMBeanRegistry, uma classe de implementação específica do JBoss JMX.
Normalmente, é necessário que um MBean estabeleça o contexto de carregamento de classe uma vez que a camada do protocolo do invocador desanexado possa não ter acessado os carregadores de classe necessários para desempacotar os tipos associados com uma invocação.
Exemplo 21.5. Bloco Quatro
...
try {
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation) {
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
...
...
try {
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation) {
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
...
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Este bloco de código instala o hash do método de classe ExposedInterface para o mapeamento do método caso o argumento da invocação for do tipo MarshalledInvocation. O mapeamento do método calculado no Exemplo 21.3, “Bloco Dois” é utilizado aqui.
Um segundo mapeamento é executado a partir do método ExposedInterface para o método correspondente da classe do MBeanServer. O InvokerServiceAdaptor descompila o ExposedInterface a partir da classe MBeanServer pela qual ele permite uma interface arbitrária. Isto é solicitado uma vez que a classe java.lang.reflect.Proxy pode apenas aplicar proxy nas interfaces. Além disso, isto permite também que você apenas exponha um sub-conjunto dos métodos MBeanServer e adicione transporte às execuções específicas tais como java.rmi.RemoteException às assinaturas do método ExposedInterface.
Exemplo 21.6. Bloco Cinco
...
// Invoke the MBeanServer method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try {
String name = method.getName();
Class[] sig = method.getParameterTypes();
Method mbeanServerMethod =
MBeanServer.class.getMethod(name, sig);
value = mbeanServerMethod.invoke(server, args);
} catch(InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw (Exception) t;
} else {
throw new UndeclaredThrowableException(t, method.toString());
}
}
return value;
} finally {
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(oldCL);
}
}
}
}
...
// Invoke the MBeanServer method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try {
String name = method.getName();
Class[] sig = method.getParameterTypes();
Method mbeanServerMethod =
MBeanServer.class.getMethod(name, sig);
value = mbeanServerMethod.invoke(server, args);
} catch(InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw (Exception) t;
} else {
throw new UndeclaredThrowableException(t, method.toString());
}
}
return value;
} finally {
if (newCL != null && newCL != oldCL) {
thread.setContextClassLoader(oldCL);
}
}
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
O bloco do código expede a invocação de método da instância do InvokerAdaptorService MBeanServer pela qual ele foi implementado. A variável da instância do servidor é herdada a partir da super-classe ServiceMBeanSupport.
Quaisquer exceções que resultem de uma invocação refletiva são manuseadas, incluindo desembrulhar quaisquer exceções declaradas lançadas pela invocação. O código MBean encerra com o retorno do resultado com êxito da invocação do método MBeanServer.
Nota
O InvokerAdaptorService MBean não lida diretamente com quaisquer detalhes específicos de transporte. Existe um cálculo do hash de método para mapeamento do Método, mas isto é um detalhe independente de transporte.
Vamos observar agora como o InvokerAdaptorService pode ser usado para expor a mesma interface org.jboss.jmx.adaptor.rmi.RMIAdaptor através do RMI/JRMP, conforme visto na Conexão para JMX Usando RMI.
Nós começamos pela apresentação da fábrica proxy e configurações InvokerAdaptorService encontradas na configuração padrão da implementação jmx-invoker-adaptor-service.sar. O Exemplo 21.7, “Descritor da implantação jmx-invoker-adaptor-server.sar padrão” apresenta o descritor jboss-service.xml para esta implantação.
Exemplo 21.7. Descritor da implantação jmx-invoker-adaptor-server.sar padrão
<server>
<!-- The JRMP invoker proxy configuration for the InvokerAdaptorService -->
<mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
name="jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory">
<!-- Use the standard JRMPInvoker from conf/jboss-service.xml -->
<attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
<!-- The target MBean is the InvokerAdaptorService configured below -->
<attribute name="TargetName">jboss.jmx:type=adaptor,name=Invoker</attribute>
<!-- Where to bind the RMIAdaptor proxy -->
<attribute name="JndiName">jmx/invoker/RMIAdaptor</attribute>
<!-- The RMI compatible MBeanServer interface -->
<attribute name="ExportedInterface">org.jboss.jmx.adaptor.rmi.RMIAdaptor</attribute>
<attribute name="ClientInterceptors">
<iterceptors>
<interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
<interceptor>
org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor
</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</iterceptors>
</attribute>
<depends>jboss:service=invoker,type=jrmp</depends>
</mbean>
<!-- This is the service that handles the RMIAdaptor invocations by routing
them to the MBeanServer the service is deployed under. -->
<mbean code="org.jboss.jmx.connector.invoker.InvokerAdaptorService"
name="jboss.jmx:type=adaptor,name=Invoker">
<attribute name="ExportedInterface">org.jboss.jmx.adaptor.rmi.RMIAdaptor</attribute>
</mbean>
</server>
<server>
<!-- The JRMP invoker proxy configuration for the InvokerAdaptorService -->
<mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
name="jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory">
<!-- Use the standard JRMPInvoker from conf/jboss-service.xml -->
<attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
<!-- The target MBean is the InvokerAdaptorService configured below -->
<attribute name="TargetName">jboss.jmx:type=adaptor,name=Invoker</attribute>
<!-- Where to bind the RMIAdaptor proxy -->
<attribute name="JndiName">jmx/invoker/RMIAdaptor</attribute>
<!-- The RMI compatible MBeanServer interface -->
<attribute name="ExportedInterface">org.jboss.jmx.adaptor.rmi.RMIAdaptor</attribute>
<attribute name="ClientInterceptors">
<iterceptors>
<interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
<interceptor>
org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor
</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</iterceptors>
</attribute>
<depends>jboss:service=invoker,type=jrmp</depends>
</mbean>
<!-- This is the service that handles the RMIAdaptor invocations by routing
them to the MBeanServer the service is deployed under. -->
<mbean code="org.jboss.jmx.connector.invoker.InvokerAdaptorService"
name="jboss.jmx:type=adaptor,name=Invoker">
<attribute name="ExportedInterface">org.jboss.jmx.adaptor.rmi.RMIAdaptor</attribute>
</mbean>
</server>
Copy to ClipboardCopied!Toggle word wrapToggle overflow
O primeiro MBean, org.jboss.invocation.jrmp.server.JRMPProxyFactory, é a fábrica proxy do serviço MBean que cria proxies para o protocolo RMI/JRMP. Conforme apresentado no Exemplo 21.7, “Descritor da implantação jmx-invoker-adaptor-server.sar padrão” a configuração deste serviço declara que o JRMPInvoker será usada como invocador desanexado, o InvokerAdaptorService é o mbean de destino pelo qual solicitações serão enviadas, que o proxy irá expor a interface RMIAdaptor. O proxy será vinculado ao JNDI sob o nome de jmx/invoker/RMIAdaptor, além de conter 3 interceptores: ClientMethodInterceptor, InvokerAdaptorClientInterceptor e InvokerInterceptor. A configuração do InvokerAdaptorService apenas determina a interface RMIAdaptor que o serviço está expondo.
O último trecho de configuração para exposição do InvokerAdaptorService através do RMI/JRMP é o invocador desanexado. O invocador desanexado que usaremos é o invocador RMI/JRMP usado pelos recipientes EJB para invocações remotas e principais, além de ser o serviço MBean org.jboss.invocation.jrmp.server.JRMPInvoker configurado no descritor conf/jboss-service.xml. Uma das naturezas desanexadas dos invocadores é que podemos usar a mesma instância de serviço. O JRMPInvoker age simplesmente como um ponto final do RMI/JRMP para todos os proxies independente da(s) interface(s) que os proxies expõem ou o serviço que os proxies utilizam.
Ajudamos os usuários da Red Hat a inovar e atingir seus objetivos com nossos produtos e serviços com conteúdo em que podem confiar. Explore nossas atualizações recentes.
Tornando o open source mais inclusivo
A Red Hat está comprometida em substituir a linguagem problemática em nosso código, documentação e propriedades da web. Para mais detalhes veja o Blog da Red Hat.
Sobre a Red Hat
Fornecemos soluções robustas que facilitam o trabalho das empresas em plataformas e ambientes, desde o data center principal até a borda da rede.