Architekturen für verteilte Internetdienste

Werbung
1 Überblick
■ Projekt-Aufbau (in Eclipse)
◆ Verzeichnisstruktur
Architekturen für
verteilte Internetdienste
◆ Build-Prozess, Launchers
■ Beans
◆ Container-Managed Persistence
◆ Finders, Selectors
◆ Bean-Referenzen
Übung 5: Enterprise JavaBeans
■ Deskriptoren
■ Client
Projekt-Beispiel
■ Application-Server / Demo
◆ Web-Konsole
◆ Datenbank
5.41
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
2 Projekt-Aufbau
2 Projekt-Aufbau (2)
■ Eclipse als Entwicklungsumgebung
■ Build-Prozess
◆ hier ohne weitere Plugins
◆ Implementierung in Eclipse
◆ Inkrementeller Compiler übersetzt im Hintergrund
■ Verzeichnisstruktur
◆ Erzeugen der IIOP-Stubs für den Client
◆ src/ – Quellcode
◆ Paketierung
◆ bin/ – Launchers, Shellscripts
◆ Deployment
◆ etc/ – Deskriptoren
◆ Client starten
◆ lib/ – J2EE-Bibliothek
◆ src-gen/ – Generierter Quellcode
▲ Server und Datenbank vorher einzeln starten, danach stoppen (s.u.)
◆ avid.ear – Application Archive
■ Launchers
◆ avid-cli.jar – Client Archive
◆ „External Tools“, um Targets im ANT Buildfile zu starten
◆ avid-ejb.jar – Bean Archive
◆ „Java Application Launcher“, um Client in Eclipse zu starten
◆ build.xml – ANT Buildfile
5.42
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.43
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
2 Projekt-Aufbau (3)
2.1 IIOP-Stubs
■ Probleme im Betrieb
■ Mittels Launcher für ANT-Target
<target name="stubs">
◆ Application Server und Datenbank laufen als eigenständige Prozesse
<rmic base="classes" iiop="true"
classpath="classes:lib/j2ee.jar"
classname="avid.u5.TaskControllerHome" />
• Debugging unkomfortabel
• Plugins starten sie in Eclipse Debugging-Context
◆ Deployment schlägt fehl…
<delete dir="classes/org"/>
• Kompletter Eclipse-Build + Refresh + Paketierung
</target>
• Undeployment
• Datenbanktabellen löschen → SQL-Tool
◆ Stubs für org.omg-Klassen werden gelöscht
• Deployment erneut versuchen
◆ Stubs für avid.u5.TaskController werden transitiv mitgeneriert
• Einzelne Beans deaktivieren, Fehler eingrenzen…
■ Oder per Shellskript
rmic -classpath classes:lib/j2ee.jar -d classes -iiop \
avid.u5.TaskControllerHome avid.u5.TaskController
5.44
5.45
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
2.2 Paketierung
2.2 Paketierung (2)
■ Mindestens 2 Archive notwendig
■ Bean Archive (…)
◆ Bean Archive: avid-ejb.jar
◆ ANT-Target
◆ Application Archive: avid.ear
<target name="jar" description="avid-ejb.jar">
◆ Web Archive, Client Archive, … (hier nicht gezeigt)
<delete file="avid-ejb.jar"/>
◆ Weitere (hinzugekaufte) Bean Archives mit Programmteilen
<jar destfile="avid-ejb.jar" manifest="etc/MANIFEST.MF">
✱ Aufbau der Archive muss strikt eingehalten werden!
<zipfileset dir="etc" prefix="META-INF">
<include name="ejb-jar.xml" />
<include name="sun-ejb-jar.xml" />
</zipfileset>
■ Bean Archive
◆ Unterverzeichnis „META-INF“
<zipfileset dir="classes"
includes="**/*.class" excludes="**/www/**/*.*">
<exclude name="avid/u5/Client.class"/>
<exclude name="**/_*_Stub.class"/>
</zipfileset>
</jar>
</target>
• Bean Descriptor: ejb-jar.xml
• Bean Descriptor: sun-ejb-jar.xml (Server-spezifisch)
◆ Unterverzeichnis „classes“
• Bean-Klassen
5.46
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.47
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
2.2 Paketierung (3)
2.2 Paketierung (4)
■ Application Archive
■ Application Archive (…)
◆ ANT-Target
◆ Ebenfalls eine JAR-Datei
<target name="ear" description="avid.ear">
◆ Unterverzeichnis „META-INF“
<delete file="avid.ear"/>
• Application Descriptor: application.xml
<jar destfile="avid.ear" manifest="etc/MANIFEST.MF">
• Application Descriptor: sun-application.xml (Server-spezifisch)
<zipfileset dir="etc" prefix="META-INF">
<include name="application.xml" />
<include name="sun-application.xml" />
</zipfileset>
◆ Wurzelverzeichnis „.“
• Bean Archive
• Web Archive, weitere Archive, … (hier nicht notwendig)
<zipfileset dir=".">
<include name="avid-ejb.jar" />
</zipfileset>
</jar>
</target>
5.48
5.49
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
2.3 Deployment
2.3 Deployment (2)
■ „Hot/Auto Deployment“
■ ANT-Targets
◆ Application Archive wird in spezielles Verzeichnis kopiert
<target name="sun-deploy">
<copy file="avid.ear"
todir="${SunAS}/domains/domain1/autodeploy"/>
</target>
◆ Application Server bemerkt und integriert es
◆ Datenbank-Tabellen werden ggf. erzeugt
▲ Datenbank vorher starten! (s.u.)
<target name="sun-undeploy">
<delete file="${SunAS}/domains/domain1/autodeploy/avid.ear"/>
</target>
■ Server-Logfile beobachten
◆ Fehler in Deskriptoren/Code hier durch Exceptions angezeigt
▲ Ende des Vorgangs abwarten!
■ Undeployment
◆ EAR aus Deployment-Verzeichnis löschen…
◆ Datenbank-Tabellen werden ggf. entfernt
5.50
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.51
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
3 Beans
3.1 Container-Managed Persistence (2)
■ Bean-Interface
Themen: CMP, Home-Methods, Finders/Selectors, Bean-Referenzen
public interface Task extends EJBObject {
3.1 Container-Managed Persistence
public Integer getId() throws RemoteException;
public void setId(Integer id) throws RemoteException;
◆ Erzeugen, Löschen von Objekten
public String getDescription() ...;
public void setDescription(String text) ...;
◆ Autonomes Laden, Sichern der Datenfelder
◆ Integrität von Bean-zu-Bean-Relationen
public Date getDue() ...;
public void setDue(Date date) ...;
◆ Einhaltung von Konsistenzbedingungen
■ Programmiermodell
public boolean getCompleted() ...;
public void setCompleted(boolean value) ...;
◆ Abstrakte Methoden → Implementiert in abgeleiteter Klasse des Containers
• In der Bean-Klasse
public TaskData getData() ...;
public void setData(TaskData data) ...;
◆ EJB-QL für Finder/Selectors → Umsetzung in Datenbank-Abfragen
}
• Im Deployment-Descriptor
5.52
5.53
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
3.1 Container-Managed Persistence (3)
3.1 Container-Managed Persistence (4)
■ Bean-Klasse
■ Bean-Klasse (…)
abstract public class TaskBean implements EntityBean {
public
public
public
public
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger(
TaskBean.class.getName());
void
void
void
void
ejbActivate() ... {}
ejbPassivate() ... {}
ejbLoad() ... {}
ejbStore() ... {}
public void unsetEntityContext() ... {
log.info("unset entity context");
this.context = null;
}
private EntityContext context;
public Integer ejbCreate()
throws CreateException, RemoteException {
log.info("create");
setId(42);
return null; // for CMP return null!
}
public void setEntityContext(EntityContext context) ... {
log.info("set entity context");
this.context = context;
}
public void ejbPostCreate() ... { }
...
public void ejbRemove() ... {}
...
5.54
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.55
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
3.1 Container-Managed Persistence (5)
3.1 Container-Managed Persistence (6)
■ Bean-Klasse (…) Home Methods
■ Bean-Klasse (…) Finders, Selectors
public int ejbHomeCountTasks() throws RemoteException {
try {
int c = ejbSelectCountTasks();
return c;
}
catch(FinderException e) { ... }
}
abstract public int ejbSelectCountTasks()
throws FinderException, RemoteException;
abstract public Collection ejbSelectGetTaskIDs()
throws FinderException, RemoteException;
abstract public Integer ejbFindByPrimaryKey(Integer id)
throws FinderException, RemoteException;
public int[] ejbHomeGetTaskIDs() throws RemoteException {
try {
Collection ids = ejbSelectGetTaskIDs();
int[] ida = new int[ids.size()];
int i=0;
for (Object o: ids)
ida[i++] = (Integer) o;
return ida;
}
catch(FinderException e) { ... }
}
...
5.56
5.57
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
3.1 Container-Managed Persistence (7)
3.1 Container-Managed Persistence (8)
■ Bean-Klasse (…) CMP-„Instanzvariablen“, Methoden
■ Bean-Home
abstract public Integer getId() throws RemoteException;
abstract public void setId(Integer id) throws RemoteException;
public interface TaskHome extends EJBHome {
public Task create() throws CreateException, RemoteException;
abstract public String getDescription() ...;
abstract public void setDescription(String text) ...;
public int countTasks() throws RemoteException;
public int[] getTaskIDs() throws RemoteException;
...weitere Methoden...
public Task findByPrimaryKey(Integer id)
throws FinderException, RemoteException;
public TaskData getData() throws RemoteException {
return new TaskData(
getDescription(), getDue(), getCompleted() );
}
}
public void setData(TaskData data) throws RemoteException {
setDescription(data.getDescription());
setDue(data.getDue());
setCompleted(data.getCompleted());
}
}
5.58
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.59
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
3.2 Home-Methods, Finders, Selectors
3.3 Bean-Referenzen
■ Home-Methods
■ Referenzen zwischen Beans müssen deklariert werden
◆ Als ejbHomeM… im Bean implementiert, im Home deklariert
◆ Um JNDI-Einträge verwalten zu können
◆ Achtung Camel-Case: ejbHomeMethodName() → methodName()
◆ Zur Unterstützung der Koordinierung im Container
■ Finders
■ Varianten
◆ findByPrimaryKey() im Home liefert Bean-Referenz
◆ Innerhalb eines Bean-Archive
◆ abstract ejbFindByPrimaryKey() im Bean liefert PrimaryKey-Objekt
◆ Innerhalb eines Application-Archive
◆ Varianten mit Collection für Ergebnismenge
◆ Zwischen Anwendungen
■ Selectors ähnlich
■ Deskriptor enthält pro Bean <ejb-ref> Elemente
◆ Namenspräfix ejbSelect…
◆ ejb-ref-name benennt lokale Forderung
◆ Ebenfalls abstract, Bean-intern ohne externe Repräsentation im Home
◆ Archiv-lokal: <ejb-link> realisiert Verbindung auf <ejb-name> der Ziel-Bean
✱ EJB-QL zu Finders/Selectors s.u.
◆ Archiv-übergreifend: zusätzlich Abbildung im Application Descriptor
• <ejb-ref-name> wird auf (ggf. externes) JNDI-Ziel abgebildet
5.60
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.61
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
4 Deskriptoren
4 Deskriptoren (2)
■ ejb-jar.xml
■ ejb-jar.xml (…) Session TaskController
<?xml version="1.0" encoding="UTF-8"?>
<enterprise-beans>
<!--DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD
Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejbjar_2_0.dtd"-->
<session>
<description/>
<display-name>The Task Controller</display-name>
<ejb-jar version = "2.1"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
<description/>
<display-name>avid implementation</display-name>
...
<ejb-name>TaskController</ejb-name>
...
<ejb-ref>
<description>Reference to the Task entity</description>
<ejb-ref-name>ejb/task</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>avid.u5.TaskHome</home>
<remote>avid.u5.Task</remote>
<ejb-link>Task</ejb-link>
</ejb-ref>
...
</session>
5.62
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.63
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
4 Deskriptoren (3)
4 Deskriptoren (4)
■ ejb-jar.xml (…) Entity Task
■ ejb-jar.xml (…) Entity Task → ejbFindByPrimaryKey ohne Query!
<entity>
<ejb-name>Task</ejb-name>
...
<home>avid.u5.TaskHome</home>
<remote>avid.u5.Task</remote>
<ejb-class>avid.u5.TaskBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.Integer</prim-key-class>
...
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Task</abstract-schema-name>
<cmp-field> <field-name>id</field-name> </cmp-field>
<cmp-field> <field-name>description...
<cmp-field> <field-name>due...
<cmp-field> <field-name>completed...
<primkey-field>id</primkey-field>
5.64
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
<query>
<description>Count all tasks.</description>
<query-method>
<method-name>ejbSelectCountTasks</method-name>
<method-params/>
</query-method>
<ejb-ql> <![CDATA[
SELECT COUNT(t) FROM Task as t
]]> </ejb-ql>
</query>
<query>
<description>Get all task IDs</description>
<query-method>
<method-name>ejbSelectGetTaskIDs</method-name>
<method-params/>
</query-method>
<ejb-ql><![CDATA[
SELECT t.id FROM Task as t
]]></ejb-ql>
</query>
</entity>
</enterprise-beans>
5.65
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
4 Deskriptoren (5)
4 Deskriptoren (6)
■ ejb-jar.xml (…)
■ sun-ejb-jar.xml (in Auszügen!)
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>Task</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
5.66
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
<sun-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>Task</ejb-name>
<jndi-name>ejb/task</jndi-name>
<cmp/>
<is-read-only-bean>false</is-read-only-bean>
<gen-classes/>
</ejb>
<cmp-resource>
<jndi-name>jdbc/__default</jndi-name>
<default-resource-principal>
<name>APP</name> <password>APP</password>
</default-resource-principal>
<create-tables-at-deploy>true</create-tables-at-deploy>
<drop-tables-at-undeploy>true</drop-tables-at-undeploy>
<database-vendor-name>derby</database-vendor-name>
</cmp-resource>
</enterprise-beans>
</sun-ejb-jar>
5.67
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5 Client (in Auszügen!)
6 Application-Server
■ Erzeugt einen Task mit ID=42, listet Tasks auf, löscht Task 42 wieder
■ Getrennte Launchers/ANT-Targets für Server und DB
Context env= new InitialContext(icenv); // kein "java:comp/env" !
Object tch_ = env.lookup("ejb/taskctrl");
TaskControllerHome tch = (TaskControllerHome)
PortableRemoteObject.narrow(tch_, TaskControllerHome.class);
TaskController tc = tch.create();
int TID = tc.createTask("...", Calendar.getInstance().getTime());
◆ Application Server
<target name="sun-start">
<exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}">
<arg value="start-domain"/>
<arg value="domain1"/>
</exec>
</target>
<target name="sun-stop">
<exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}">
<arg value="stop-domain"/>
<arg value="domain1"/>
</exec>
</target>
out.println("Listing "+tc.countTasks()+" tasks:");
for (int id: tc.getTaskIDs()) {
TaskData td = tc.getTaskData(id);
out.println("\nTask "+id+": "+td.getDue());
tc.deleteTask(TID);
tc.remove();
tc=null; tch=null;
◆ TaskController.createTask() erneut möglich?
5.68
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.69
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
6 Application-Server (2)
7 Aufgaben
■ Getrennte Launchers/ANT-Targets für Server und DB (…)
■ Diff der Übungsaufgaben zu EJB studieren
◆ Datenbank
◆ Stateless Session Bean mit Hash (Demo aus Vorlesung)
<target name="sun-db-start">
<exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}">
<arg value="start-database"/>
</exec>
</target>
<target name="sun-db-stop">
<exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}">
<arg value="stop-database"/>
</exec>
</target>
◆ Entity mit Container-Managed Persistence (dieses Projekt)
◆ In Eclipse: beide Projekte markieren, Mouse: [Compare With, Each Other…]
■ Beispiel ausbauen
◆ Team.ejbCreate() um Parameter erweitern
◆ Team.id automatisch erzeugen, inkrementieren
■ Web-Client
◆ Servlets, JSP, JSF benutzen
▲ Arbeitsverzeichnis im Attribut „dir“ muss korrekt gesetzt sein,
da Dateien der Datenbank sonst falsch abgelegt!
◆ Benutzer-Login
◆ TeamController als Stateful Session Bean notwendig!
■ Integrierte Datenbank „Apache-Derby“
◆ JDBC-URL: „jdbc:derby://localhost/sun-appserv-samples;create“
5.70
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
5.71
© 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/
Herunterladen