使用Jini连接代理
立即解锁
发布时间: 2025-08-18 02:06:06 阅读量: 3 订阅数: 6 

### 使用Jini连接代理
#### 1. 背景与Jini连接器概述
在远程访问JMX代理时,RMI连接器能让我们调用MBean服务器方法并接收通知,但它有个缺点,即必须知道RMI连接器服务器的地址。为解决这个问题,可以构建Jini连接器。Jini能让开发者编写可自我描述且可被客户端发现的服务,使用Jini连接器,无需客户端知道代理的确切位置就能分发JMX代理。
例如,想要与JMX代理交互的客户端可以构建一个Jini连接器客户端,输入一些搜索参数,就能定位到最近匹配的代理。Jini连接器会使用其注册所在的MBean服务器的默认域名来宣传自己,Jini连接器客户端则使用该域名作为搜索参数来搜索代理。
Jini连接器由三个组件组成:
- **MBean**:允许通过MBean服务器管理连接器,就像RMI连接器和HTML适配器MBean一样。
- **Jini服务**:由MBean创建,允许客户端连接到代理。
- **Jini客户端**:用于定位代理的Jini服务。
#### 2. Jini连接器组件详细介绍
##### 2.1 MBean
MBean在连接器中的作用是设置和管理Jini服务,它让代理能够控制Jini服务,包括设置其描述以及决定何时使服务可被发现。MBean包含对其MBean服务器的引用,这使得Jini服务可以回调MBean服务器的方法。MBean组件由`JINIServerMBean`接口和`JINIServer`类(实现`JINIServerMBean`接口)定义。
`JINIServerMBean`接口暴露的属性和操作如下表所示:
| 属性/操作 | 描述 |
| --- | --- |
| Domain | 只读属性,指示包含此连接器的代理的域。 |
| EntryName | 读写属性,为MBean启动的Jini服务提供一个标识符。此属性可选,但提供值能让客户端更精确地搜索服务。 |
| Groups | 读写属性,指示Jini服务将向哪些查找服务组注册。 |
| enableConnections | 操作,告诉MBean启动Jini服务。 |
`JINIServerMBean`接口代码如下:
```java
package jmxbook.ch9;
public interface JINIServerMBean
{
public String getDomain();
public String getEntryName();
public void setEntryName( String name );
public String[] getGroups();
public void setGroups( String[] groups );
public void enableConnections();
}
```
`JINIServer`类实现了`JINIServerMBean`、`MBeanRegistration`和`ServiceIDListener`三个接口,其代码如下:
```java
package jmxbook.ch9;
import javax.management.*;
import java.rmi.*;
import java.util.*;
import net.jini.discovery.*;
import net.jini.core.lookup.*;
import net.jini.lookup.*;
import net.jini.lease.*;
import net.jini.core.discovery.*;
import net.jini.lookup.entry.*;
import net.jini.core.entry.*;
public class JINIServer implements JINIServerMBean,
MBeanRegistration,
ServiceIDListener
{
private MBeanServer mbs = null;
private JoinManager jm = null;
private ServiceID id = null;
private String domain = null;
private ObjectName name = null;
private String[] groups;
private Name entry = null;
private boolean enabled = false;
public JINIServer()
{
groups = new String[ 1 ];
groups[ 0 ] = "public";
}
public String getDomain()
{
return domain;
}
public String getEntryName()
{
return entry.name;
}
public void serviceIDNotify( ServiceID id )
{
this.id = id;
}
public ObjectName preRegister( MBeanServer server,
ObjectName name) throws Exception
{
this.mbs = server;
if( name == null )
{
name =
new ObjectName( mbs.getDefaultDomain() +
":connectorType=JINI" );
}
this.domain = name.getDomain();
return name;
}
public void postRegister (Boolean registrationDone) {}
public void preDeregister() throws Exception {}
public void postDeregister(){}
public void setGroups( String groups[] )
{
if( groups != null )
this.groups = groups;
}
public String[] getGroups()
{
return groups;
}
public void enableConnections()
{
createService();
}
public void setEntryName( String name )
{
Entry old = entry;
this.entry = new Name( name );
if( enabled )
{
Entry[] newlabels = { entry };
Entry[] labels = { old };
jm.modifyAttributes( labels, newlabels );
}
}
private void createService()
{
try
{
JINIConnector connector =
new JINIConnectorImpl( this );
Entry[] labels = { entry };
LookupDiscoveryManager mgr =
new LookupDiscoveryManager( groups, null, null );
jm = new JoinManager(connector, labels, this,
mgr,
new LeaseRenewalManager());
enabled = true;
}
catch( Exception e )
{
e.printStackTrace();
}
}
/*
call back methods
*/
public Integer getMBeanCount() throws Exception
{
return mbs.getMBeanCount();
}
public ObjectInstance createMBean(String className,
ObjectName name) throws Exception
{
return mbs.createMBean( className, name );
}
}
```
这个类使用了Jini工具包中的多个包,用于查找查找服务以及管理和描述Jini服务。`createService()`方法负责创建Jini服务类`JINIConnectorImpl`并将其注册到可用的Jini查找服务中。
##### 2.2 Jini服务
Jini服务实现了与MBean服务器接口中每个方法对应的方法,这使得Jini客户端可以通过Jini服务将其方法调用转发到MBean服务器。Jini服务由`JINIConnectorImpl`类定义,该类实现了`JINIConnector`接口。
`JINIConnector`接口代码如下:
```java
package jmxbook.ch9;
import java.rmi.*;
import javax.management.*;
public interface JINIConnector extends Remote
{
public Integer getMBeanCount() throws JINIConnectorException;
public ObjectInstance createMBean(String className,
ObjectName name) throws JINIConnectorException;
}
```
`JINIConnectorImpl`类代码如下:
```java
package jmxbook.ch9;
import java.rmi.*;
import java.rmi.server.*;
import javax.management.*;
public class JINIConnectorImpl extends
UnicastRemoteObject implements JINIConnector
{
private JINIServer server = null;
public JINIConnectorImpl( JINIServer server )
throws RemoteException
{
this.server = server;
}
public Integer getMBeanCount() throws JINIConnectorException
{
try
{
return server.getMBeanCount();
}
catch( Exception e )
{
throw new JINIConnectorException( "getMBeanCount", e );
}
}
public ObjectInstance createMBean(String className,
ObjectName name) throws
JINIConnectorException
{
try
{
return server.createMBean( className, name );
}
catch( Exception e )
{
throw new JINIConnectorException( "createMBean", e );
}
}
}
```
为了成为Jini服务,`JINIConnectorImpl`类必须是一个远程类,因此它扩展了`UnicastRemoteObject`类,并实现了`JINIConnector`接口。该类包含对`JINIServer` MBean的引用,以便服务可以回调MBean来执行服务客户端所需的调用。
`JINIConnectorException`类用于包装服务器端异常,代码如下:
```java
package jmxbook.ch9;
import java.rmi.*;
public class JINIConnectorException extends RemoteException
{
private Exception exception = null;
public JINIConnectorException( String message, Exception ex )
{
super( message, ex );
this.exception = ex;
}
public Exception getWrappedException()
{
return exception;
}
}
```
#### 3. Jini连接器客户端
Jini连接器客户端用于发现和使用Jini连接器服务,从而使用JMX代理。客户端实现了`MBeanServer`接口,为客户端用户提供服务器端可用的所有方法。由于篇幅原因,除了`getMBeanCount()`和`createMBean()`方法外,其他方法都被存根化。
`JINIConnectorClient`类代码如下:
```java
package jmxbook.ch9;
import javax.management.*;
import java.rmi.*;
import java.util.*;
import net.jini.discovery.*;
import net.jini.core.lookup.*;
import net.jini.lookup.*;
import java.io.*;
public class JINIConnectorClient
implements DiscoveryListener, MBeanServer
{
private ServiceTemplate template = null;
private LookupDiscovery reg = null;
private JINIConnector server =null;
public JINIConnectorClient()
{
System.setSecurityManager( new RMISecurityManager() );
Class[] cls = { JINIConnector.class };
template = new ServiceTemplate( null, cls, null );
try
{
reg = new LookupDiscovery( new String[] { "" } );
reg.addDiscoveryListener( this );
while( server == null )
Thread.sleep( 1000 );
}
catch( Exception e )
{
e.printStackTrace();
}
}
public void discovered( DiscoveryEvent event )
{
if( server != null )
return;
ServiceRegistrar[] lookups = event.getRegistrars();
try
{
ServiceMatches items = lookups[0].lookup( template,
Integer.MAX_VALUE );
server = ( JINIConnector ) items.items[ 0 ].service;
System.out.println( "service found" );
}
catch( Exception e )
{
e.printStackTrace();
}
}
public void discarded( DiscoveryEvent event ){}
public Integer getMBeanCount()
{
try
{
return server.getMBeanCount();
}
catch( JINIConnectorException e )
{
return null;
}
}
public ObjectInstance createMBean(String className,
ObjectName name)
throws ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException
{
try
{
return server.createMBean( className, name );
}
catch( JINIConnectorException e )
{
Exception ex = e.getWrappedException();
if( ex instanceof ReflectionException )
throw ( ReflectionException ) ex;
else if( ex instanceof InstanceAlreadyExistsException )
throw ( InstanceAlreadyExistsException ) ex;
else if( ex instanceof MBeanRegistrationException )
throw ( MBeanRegistrationException ) ex;
else if( ex instanceof MBeanException )
throw ( MBeanException ) ex;
else
throw ( NotCompliantMBeanException ) ex;
}
}
/*
UNIMPLEMENTED METHODS BELOW
*/
public Object instantiate(String className)
throws ReflectionException,
MBeanException { return null; }
public Object instantiate(String className,
ObjectName loaderName)
throws ReflectionException, MBeanException,
InstanceNotFoundException { return null; }
public Object instantiate(String className, Object params[],
String signature[])
throws ReflectionException, MBeanException
{ return null; }
public Object instantiate(String className,
ObjectName loaderName,
Object params[], String signature[])
throws ReflectionException, MBeanException,
InstanceNotFoundException { return null; }
public ObjectInstance createMBean(String className,
ObjectName name
```
0
0
复制全文
相关推荐










