1 Überblick Architekturen für verteilte Internetdienste Java Remote Method Invocation Java Beans Java Management Extensions Übung 2: Java RMI, Java Beans und Java Management Extensions (JMX) holger.schmidt@uni-ulm.de Fernaufrufmechanismus für Java Erhalt der Java Aufrufsemantik Primitive Datentypen und nicht exportierte RMI Objekte: Call-By-Value Exportierte RMI Objekte: Call-By-Reference Architektur: Implementierung eines einfachen Hello World Beispiels Interface public interface Hello extends java.rmi.remote { public String sayhello() throws java.rmi.remoteexception; Implementierung Client Server public class HelloImpl extends UnicastRemoteObject implements Hello { Stub Remote Reference Layer Transport Layer Skeleton Remote Reference Layer 2.1 public String sayhello() throws java.rmi.remoteexception { return Hello World! ; 2.2
Main-Methode: HelloImpl hello = new HelloImpl(); java.rmi.naming.rebind("//<host>:<port>/hello", hello); Codebase zum dynamischen Laden von Code am Server: System.setProperties() VM-Property: java -Djava.rmi.server.codebase=<URL> Security Manager System.setSecurityManager(new java.rmi.rmisecurity Manager()) Policy-File mit Rechten grant { //permission java.security.allpermission; permission java.net.socketpermission localhost:1099, connect, resolve, accept ; ; 2.3 RMI Registry <java_path>/bin/rmiregistry[.exe] Darf keinen direkten Zugriff auf Classpath der Objekte haben Codebase würde eliminiert Client erhält Stub ohne Codebase-Annotation Implementierung des Clients Hello hello; hello = (Hello)java.rmi.Naming.lookup("//<host>:<port>/Hello"); System.out.println(hello.sayHello()); 2.4 Stub-Generierung rmic [-keep] HelloImpl Nicht verwechseln mit Enterprise Java Beans (EJB)!!! JavaBeans API Specification public java.lang.string sayhello()...{ if (usenewinvoke) { Object $result = ref.invoke(this, $method_sayhello_0, null, 1253370244719889472L); else { java.rmi.server.remotecall call = ref.newcall( (RemoteObject)this,operations,0,interfaceHash); ref.invoke(call); ref.done(call); Dynamische Proxies (ab Java 1.5) Implementieren beliebige Typen Generische Dispatch-Methode invoke(...) JVM Parameter beim Starten des Servers: -Djava.rmi.server.ignoreStubClasses=true 2.5 Ziel: Einfaches Komponentensystem Eigenschaften Unterstützung von Introspection Unterstützung von Customization Unterstützung von Events Unterstützung von Properties Unterstützung von Persistenz (Serialization, Externalization) 2.6
Eigenschaften Zugriff nur über Methoden möglich (Kapselung) Lesender Zugriff: get<property>() Schreibender Zugriff: set<property>() private int value; void setvalue(int value); int getvalue(); Indizierte Eigenschaften (Vektoren) private int[] value; void setvalue(int index, int value); int getvalue(int index); void setvalue(int values[]); int[] getvalue(); Boolsche Eigenschaften private boolean value; void setvalue(boolean value); int isvalue(); 2.7 2.8 Gebundene Eigenschaften void addpropertychangelistener(propertychangelistener x); void removepropertychangelistener(propertychangelistener x); Veto-Eigenschaften void addvetoablechangelistener(vetoablechangelistener x); void removevetoablechangelistener(vetoablechangelistener x); Unterstützung einschalten private PropertyChangeSupport changes = new PropertyChangeSupport(this); Unterstützung einschalten private VetoableChangeSupport vetos = new VetoableChangeSupport(this); void addpropertychangelistener(propertychangelistener l) { changes.addpropertychangelistener(l); void removepropertychangelistener(propertychangelistener l){... void addvetoablechangelistener(vetoablechangelistener l) { vetos.addvetoablechangelistener(l); void removevetoablechangelistener(vetoablechangelistener l){... void setvalue(int value){ this.value = value; changes.firepropertychange( value, oldvalue, newvalue); 2.9 public void setvalue(int value) throws PropertyVetoException { int oldvalue = this.value; vetos.firevetoablechange( value, oldvalue, value); this.value = value; 2.10
Filter (Optional) void addpropertychangelistener(string propertyname, PropertyChangeListener listener); void removepropertychangelistener(string propertyname, PropertyChangeListener listener); void addvetoablechangelistener(string propertyname, VetoableChangeListener listener); void removevetoablechangelistener(string propertyname, VetoableChangeListener listener); Packaging Java Archive (JAR) Spezielles Manifest (META-INF/MANIFEST.MF) Name: avid/example/bean.class Java-Bean: True Depends-On: avid/example/bean2.class Explizite Spezifikation mit BeanInfo Klasse Listet Leistungen nach Außen explizit auf Zuordnung von Icons für Beans Später mehr... 2.11 2.12 (JMX) Java auf dem Server Überwachung zur Laufzeit JMX bietet einheitliche Schnittstelle (nicht proprietär) Architektur (aus Java Management Extensions Instrumentation and Agent Specification, v1.2) Entstanden im Rahmen von JSR 3 (IBM, Bea Systems, Borland, etc.) JSR 176: JMX als Standard in Java 1.5 Anforderungen an Anwendungen sind minimal 2.13 2.14
Architektur Instrumentation Level Zu überwachende Resourcen Repräsentiert durch MBeans Benachrichtigungsmechanismus zum Informationsaustausch zwischen MBeans MBean Repräsentiert überwachbare Ressource Management-Schnittstelle für MBean Server Attribute Operationen Benachrichtigungen Konstruktor Agent Level Agenten sprechen zu verwaltende Ressourcen direkt an Stellen diese entfernten Anwendungen zur Verfügung MBeans registrieren sich am MBean Server Distributed Services Level Entferntes Management: Protokoll-Adapter, Standard Konnektoren 2.15 4 Typen Standard MBean Dynamic MBean Model MBean Open MBean 2.16 Standard MBean Einfachste Möglichkeit Statisches Management Interface Suffix MBean public interface JMXTestMBean { public void sayhello(); public int getvalue(); public void setvalue(int value); Dynamic MBean Dynamische Management Schnittstelle Implementiert javax.management.dynamicmbean public interface DynamicMBean { public Object getattribute(string attribute) throws (...); public void setattribute(attribute attribute) throws (...); public AttributeList getattributes(string[] attributes); public AttributeList setattributes(attributelist attributes); public Object invoke(string actionname, Object params[], String signature[])throws (...); public MBeanInfo getmbeaninfo(); dmbeaninfo = new MBeanInfo(dClassName, ddescription, dattributes, dconstructors, doperations, dnotifications); 2.17 2.18
Model MBean Erweiterung der Dynamic MBean Interface javax.management.persistentmbean Zusätzlich load() und store() Methoden Open MBean Mechanismus, neue Objekte zur Laufzeit zu verstehen und zu verwenden Implementiert javax.management.dynamicmbean Open: Signaturen basieren auf kleiner Menge Java-Typen (Void, Integer, Byte,...) Veröffentlichen OpenMBeanInfo Objekt Sofortige Verwendung ohne Neuübersetzung abhängiger Klassen Beispiel (Standard MBean) public interface JMXTestMBean { public void sayhello(); public String getname(); public int getvalue(); public void setvalue(int value); public static void main(string[] args) { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("avid.u2:type=JMXTest"); JMXTest mbean = new JMXTest(); mbs.registermbean(mbean, name); Thread.sleep(Long.MAX_VALUE); 2.19 2.20 Benachrichtigungen (vgl. Java Beans) Klasse erbt von NotificationBroadcasterSupport public class JMXTest extends NotificationBroadcasterSupport implements JMXTestMBean { public MBeanNotificationInfo[] getnotificationinfo() { String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE ; String name; name = AttributeChangeNotification.class.getName(); String descript = "Attribute of this MBean has changed"; MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, descript); return new MBeanNotificationInfo[] {info; 2.21 Benachrichtigungen (vgl. Java Beans) private long sequencenumber = 1; public void setvalue(int value) { int oldvalue = this.value; this.value=value; Notification n = new AttributeChangeNotification(this, sequencenumber++, System.currentTimeMillis(), "Value changed", "Value", "int", oldvalue, this.value ); sendnotification(n); 2.22
Wichtig: Starten mit JVM-Parameter -Dcom.sun.management.jmxremote Management mit jconsole (<JDK_HOME>/bin) 5 Aufgaben Java RMI Implementierung eines einfachen Zeitservers: Methode gettime() gibt aktuelle Uhrzeit zurück Mit/ohne Stub-Erzeugung Variante: gettime() gibt Uhrzeitobjekt zurück Java Objekt Exportiertes Java RMI-Objekt 2.23 Java Beans VetoableChangeListener vs. Event Listener Interface Java Management Extensions (JMX) Beispiel aus Übung online (selbst ausprobieren) Dynamic MBean Implementierung http://java.sun.com/j2se/1.5.0/docs/guide/jmx/examples.html 2.24