# Input / Outputstreams über EJBs?



## peez (14. Jun 2010)

Ich habe eine Stateless Session Bean, die vom Client Dateiinhalte bekommt und sie auf dem Server speichert.

Momentan wird einfach ein byte-Array übergeben.

Bei großen Dateien kann das natürlich Probleme mit dem verfügbaren Speicher an Client u. Server geben... Kann man einer EJB denn auch irgendwie einen Stream übergeben, wo dann am Server ganz normal ausgelesen wird?
Falls nicht - was würdet ihr optimalerweise machen? Dachte da an einen Segmentierungsmechanismus, der dann eben Dateien segmentiert überträgt, am Server auf Festplatte zwischenspeichert u. wenn alles da ist erst zusammenfügt u. wegspeichert. Fänd ich aber nicht so schön...


----------



## Niki (14. Jun 2010)

Muss es eine stateless Bean sein? Wenn sie stateful wär würd ich die Datei einfach in kleinen Schritten übertragen und Methoden zum öffnen, schreiben und schließen anbieten. In etwa so (vereinfacht)


```
private FileOutputStream fos = null;

public void openFile(String name){
  if(fos == null){
    fos = new FileOutputStream(new File(name));
  } else {
    throw new IllegalStateException("file already open");
  }
}

public void writeToFile(byte[] b, int count){
  fos.write(b, 0, count);
}

public void closeFile(){
  fos.flush();
  fos.close();
}
```

ich kenn mich leider mit EJBs zu wenig aus, bei RMI würds so gehen. Wüsste daher nicht was bei EJBs dagegen sprechen sollte.

//EDIT

wenn es stateless bleiben muss, müsstest du halt irgendwo eine Art ID generieren, die ID zum Client beim open zurück liefern und den Stream in einer Map zur ID speichern. Die ID müsste man halt dann beim schreiben und schließen mit übergeben damit man den richtigen Stream holen kann. Ist aber nur theoretisch durchdacht.


----------



## peez (14. Jun 2010)

Niki hat gesagt.:


> wenn es stateless bleiben muss, müsstest du halt irgendwo eine Art ID generieren, die ID zum Client beim open zurück liefern und den Stream in einer Map zur ID speichern. Die ID müsste man halt dann beim schreiben und schließen mit übergeben damit man den richtigen Stream holen kann. Ist aber nur theoretisch durchdacht.



Ja an sowas habe ich auch gedacht. Hatte gehofft dass man auch irgendeinen Stream benutzen kann zwecks Transaction Handling etc. Wenn die Übertragung abbricht bzw. wenn aus irgendeinem Grund der nächste Teil nicht mehr übertragen wird, bleiben die Dateileichen auf der Festplatte liegen...

Mit einer Stateful hast recht da wäre das einfacher indem beim zerstören einfach auf den offenen Stream geprüft wird u. bei Bedarf die Leichen entfernt werden können.
Werde morgen mal schauen ob irgendwas dagegen spricht, die stateful zu machen...
Wie ist das denn nochmal mit dem Zerstören einer Stateful Bean? Muss man das explizit machen oder wird sie auch zerstört, wenn das RemoteInterface vom GC aufgeräumt wird bzw. durch einen Timeout?


----------



## maki (14. Jun 2010)

Laut EJB Spek. ist java.io.File verboten, weil es nicht transaktionsfähig ist, und weil es da ein Problem mit Clustering geben könnte 

k.A., aber vielleciht findest du ja einen passenden JCA.


----------



## FArt (15. Jun 2010)

JCA ist der einzig richtige Ansatz.

Unter Umständen kann man einen Umweg über Dateien in Betracht ziehen. Aber nie direkt auf die Dateien zugreifen, sondern über einen Resource Adapter gehen. Es gibt auch schon fertige File Resource Adapter.


----------



## peez (15. Jun 2010)

Wie - auch innerhalb der Bean darf ich java.io.File nicht verwenden??


----------



## FArt (15. Jun 2010)

JSR-220 EJB 3.0 Spec , EJB Core:
Kapitel 21.1.2:


> An enterprise bean must not use the java.io package to attempt to access files and directories
> in the file system.


----------



## peez (15. Jun 2010)

Hoppala.. Danke für den Hinweis. Hat das denn einen bestimmten Grund? Bisher hatte ich noch keine Ausfälle zu beklagen mit dem FileInputStream (was auch aus dem java.io package kommt)...


----------



## FArt (16. Jun 2010)

peez hat gesagt.:


> Hoppala.. Danke für den Hinweis. Hat das denn einen bestimmten Grund? Bisher hatte ich noch keine Ausfälle zu beklagen mit dem FileInputStream (was auch aus dem java.io package kommt)...



Beans werden von einem Container verwaltet. Der garantiert den laut Spec angegebenen Lebenszyklus. Was die Instanzen betrifft, und ob ein Bean als Objekt existiert oder nicht, unterliegt dem Container und seiner Optimierung. Bestimmte Ressourcen (Streams) bedingen auch einen Lebenszyklus, das passt oft nicht ganz zusammen.
Ein weiteres Thema ist die Portierbarkeit, Skaliebarkeit, Clustering. Der Container legt über Konfiguration fest, wo dein Bean existiert. Es ist nicht sichergestellt, dass der Pfad in das Filesystem auf jedem System passend existiert. 
Es gibt noch mehr Gründe... deterministisches Verhalten, transaktionales Verhalten usw.
Technisch funktioniert es natürlich, auch wenn es die Möglichkeit gäbe diese Zugriffe z.B. über einen Securitymanager zu verbieten.
Wer sich außerhalb der Spec bewegt, sollte genau wissen was er tut. Ich rate davon ab.


----------



## peez (16. Jun 2010)

FArt hat gesagt.:


> Wer sich außerhalb der Spec bewegt, sollte genau wissen was er tut.


Weiß ich natürliiiich :lol:

Ne im Ernst danke für den Hinweis. Werde ich mich auf jeden Fall näher drum kümmern, wenn mal wieder Zeit ist. So lange darf es einfach nicht fehlschlagen  Clustering etc. haben wir zwar immer auf dem Schirm, steht aber im "20-Jahres-Plan"


----------



## FArt (16. Jun 2010)

peez hat gesagt.:


> Weiß ich natürliiiich :lol:
> 
> Ne im Ernst danke für den Hinweis. Werde ich mich auf jeden Fall näher drum kümmern, wenn mal wieder Zeit ist. So lange darf es einfach nicht fehlschlagen  Clustering etc. haben wir zwar immer auf dem Schirm, steht aber im "20-Jahres-Plan"



Wenn jetzt keine Zeit ist, wann dann?

Ich verdiene mit dieser Einstellung mein Geld und kann mich nicht beschweren 
Firmen zahlen gut, wenn produktiver Code amok läuft und Image- und Geldverlust droht.


----------



## peez (16. Jun 2010)

FArt hat gesagt.:


> Wenn jetzt keine Zeit ist, wann dann?
> 
> Ich verdiene mit dieser Einstellung mein Geld und kann mich nicht beschweren
> Firmen zahlen gut, wenn produktiver Code amok läuft und Image- und Geldverlust droht.



Ich teile deine Einstellung - der Großteil unserer Programmierer leider nicht... Deshalb ist momentan auch keine Zeit weil momentan alle dran sind, was anderes zu fixen, das durch sowas ähnliches passiert ist ;(;(


----------



## maki (16. Jun 2010)

Was mich doch dann wundert ist, dass man JEE AppServer einsetzt, EJBs & etc. pp., sich aber offensichtlich noch keiner mit den Grundlagen auseinandergesetzt hat. Leider findet man sowas häufig, war auch schon in einem Projekt mit J2EE 1.4, JBoss4, Hibernate, aber MySQL als DB... wir haben uns lange gewundert, warum unsere ach so tollen Transaktionen nicht funzen... bis es dann gedämmert hat: MySQL MyISAM Tabellen unterstützen keineTransaktionen, so einfach kann es manchmal sein. Leider hätte die Änderung auf INNODB tabellen größere Änderungen am System verlangt, die Tests zB. hatten einen Deadflock bei eingeschalteten Transaktionen, und ein paar andere Stellen.
Ergebnis: Viel Aufwand, Arbeit, Technologie und Komplexität für ein Produkt, das so vergleichbare Features hatte wie eine PHP Seite oder AccessDB.


----------



## FArt (16. Jun 2010)

maki hat gesagt.:


> Was mich doch dann wundert ist, dass man JEE AppServer einsetzt, EJBs & etc. pp., sich aber offensichtlich noch keiner mit den Grundlagen auseinandergesetzt hat.



ACK


----------



## Xunil (8. Jul 2010)

Welche Resource-Adapter die das können kennt ihr? 
Ich bin bisher nur auf einen einzigen gestoßen : 
File Resource Adapter | Download File Resource Adapter software for free at SourceForge.net

Würde am liebsten einen eigenen Implementieren, sieht aber ganz schön kompliziert aus.
Kennt jemand ein Tutorial, das sich genau mit diesem Thema befasst und für JCA 1.5 ist ? 

thx


----------

