socia-platform / htwplus

The social network and new eLearning system for HTW-Berlin.
http://plus.htw-berlin.de
MIT License
14 stars 8 forks source link

Migration zu Play 2.4 #117

Closed fabiankirstein closed 8 years ago

fabiankirstein commented 9 years ago

https://playframework.com/documentation/2.4.x/Highlights24

fabiankirstein commented 9 years ago

Das ist wie immer alles nicht so leicht. Wird sicherlich etwas brauchen. Habe schon einige Abhängigkeiten erneuert, aber es knallt an allen Enden. Besonders durch die Einführung von DI in Play muss einiges gemacht. Auf den ersten Blick muss der Mailservice angepasst werden, das Plugin funktioniert jetzt etwas anders. https://github.com/playframework/play-mailer

IvenZ commented 9 years ago

Willst du das erst einmal fertig haben, bevor wir weiter Features knallen? :)

fabiankirstein commented 9 years ago

Ne, mach mal weiter.

tennox commented 9 years ago

Meinst du das: ? https://github.com/socia-platform/htwplus/commit/f7cc0c098c3c942e75f87b63e920b48e7da1f80b

Fabian Kirstein notifications@github.com schrieb am Di., 2. Juni 2015 um 22:48 Uhr:

Das ist wie immer alles nicht so leicht. Wird sicherlich etwas brauchen. Habe schon einige Abhängigkeiten erneuert, aber es knallt an allen Enden. Besonders durch die Einführung von DI in Play muss einiges gemacht. Auf den ersten Blick muss der Mailservice angepasst werden, das Plugin funktioniert jetzt etwas anders. https://github.com/playframework/play-mailer

— Reply to this email directly or view it on GitHub https://github.com/socia-platform/htwplus/issues/117#issuecomment-108094803 .

fabiankirstein commented 9 years ago

Es gibt jetzt schon Mailer 3.0 extra für Play 2.4. Denke also es ist nochmal was anderes.

fabiankirstein commented 9 years ago

@TeNNoX Mit welchem SMTP-Server testest du bei dir lokal die Mailsache?

fabiankirstein commented 9 years ago

Kleine Zwischenbericht hierzu: Ich habe alles soweit mit Play 2.4.2 zum Laufen gebracht. Es gibt noch folgende Probleme:

IvenZ commented 9 years ago

Der aktuelle Stand ist im Branch, oder? Dann könnte ich mir das auch mal angucken, wenn gewünscht.

fabiankirstein commented 9 years ago

Kannst du machen. Ist aber nicht nötig. Ich würde dich bitten es zu testen wenn ich durch bin. Ist in einem Zwischenstand. Und viele Köche....

IvenZ commented 9 years ago

Ok. Du schaffst das! :dancer: :+1:

fabiankirstein commented 9 years ago

@IvenZ Kannst du den 2.4 Branch mal testen bitte? Am besten mit einer leeren Datenbank. Ich habe folgende Probleme noch:

IvenZ commented 9 years ago

Alles klar. Werde berichten ...

IvenZ commented 9 years ago

Also bei der Evolution sind einfach die DB Tabellen noch nicht vorhanden Dann failed das natürlich. Komischerweise werden bei Play < 2.4 die Einträge vorher gemacht, bevor die Scripte ausgeführt werden. Hab noch nicht geschaut ob und wo man die Reihenfolge ändern kann

fabiankirstein commented 9 years ago

Ja genau so sehe ich das auch. Hatte ich hier schon erwähnt. Ich denke es gibt keine Lösung. Habe versucht mir Hilfe zu holen: http://stackoverflow.com/questions/31502061/play-evolutions-and-jpa-in-play-framework-2-4 Interessiert aber keinen.

IvenZ commented 9 years ago

ah stimmt. Hattest du schon einmal erwähnt. krass, 80 views und keiner scheint ne Ahnung zu haben -.-

IvenZ commented 9 years ago

Habe mal in der app.conf evolutionplugin=enabled nachgetragen (war auskommentiert) und jetzt gehts bei mir

fabiankirstein commented 9 years ago

echt? ich checke das heute abend mal bei mir.

IvenZ commented 9 years ago

Jop. und das:

Manchmal komische Fehlermeldung bzgl. Entity Manager im Notification Scheduler

kannst du wahrscheinlich nicht reproduzieren?

fabiankirstein commented 9 years ago

Ich starte das ganze ja direkt mit IntelliJ und da kommt es wenn ich die Plus neustarte.

IvenZ commented 9 years ago

Hm, ok, das habe ich noch nicht beobachten können. Aber du kannst ja mal nen stacktrace posten wenns das nächste Mal passiert.

fabiankirstein commented 9 years ago

Ok, hab es ausprobiert. Bei mir hilft evolutionplugin=enabled nicht. Bist du dir sicher, dass du die DB nochmal geleert hast vorher? Laut Doku sollte das auch nicht bringen:

"Evolutions are automatically activated if a database is configured in application.conf and evolution scripts are present. You can disable them by setting play.evolutions.enabled=false"

Zu der anderen Sache: Bekomme folgenden Fehler. Dafür muss ich einfach eine Codezeile ändern und das Hotdeploy durch Reload der Seite erzwingen. Ich glaube es ist Uhrzeit abhängig, wegen dem Scheduler. Es ist jetzt 21:49.

[info] application - Start sending of daily email notifications...
java.lang.IllegalStateException: EntityManagerFactory is closed
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.validateNotClosed(EntityManagerFactoryImpl.java:388)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:342)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
    at play.db.jpa.DefaultJPAApi.em(DefaultJPAApi.java:71)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:123)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:80)
    at play.db.jpa.JPA.withTransaction(JPA.java:127)
    at models.Notification.findUsersWithDailyHourlyEmailNotifications(Notification.java:235)
    at models.services.EmailService.sendDailyHourlyNotificationsEmails(EmailService.java:120)
    at Global.lambda$onStart$0(Global.java:61)
    at Global$$Lambda$52/1491921935.run(Unknown Source)
    at akka.actor.LightArrayRevolverScheduler$$anon$2$$anon$1.run(Scheduler.scala:242)
    at akka.actor.LightArrayRevolverScheduler$TaskHolder.run(Scheduler.scala:476)
    at akka.actor.LightArrayRevolverScheduler$$anonfun$close$1.apply(Scheduler.scala:282)
    at akka.actor.LightArrayRevolverScheduler$$anonfun$close$1.apply(Scheduler.scala:281)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
    at akka.actor.LightArrayRevolverScheduler.close(Scheduler.scala:280)
    at akka.actor.ActorSystemImpl.stopScheduler(ActorSystem.scala:689)
    at akka.actor.ActorSystemImpl$$anonfun$liftedTree2$1$1.apply$mcV$sp(ActorSystem.scala:618)
    at akka.actor.ActorSystemImpl$$anonfun$liftedTree2$1$1.apply(ActorSystem.scala:618)
    at akka.actor.ActorSystemImpl$$anonfun$liftedTree2$1$1.apply(ActorSystem.scala:618)
    at akka.actor.ActorSystemImpl$$anon$3.run(ActorSystem.scala:642)
    at akka.actor.ActorSystemImpl$TerminationCallbacks$$anonfun$run$1.runNext$1(ActorSystem.scala:809)
    at akka.actor.ActorSystemImpl$TerminationCallbacks$$anonfun$run$1.apply$mcV$sp(ActorSystem.scala:812)
    at akka.actor.ActorSystemImpl$TerminationCallbacks$$anonfun$run$1.apply(ActorSystem.scala:805)
    at akka.actor.ActorSystemImpl$TerminationCallbacks$$anonfun$run$1.apply(ActorSystem.scala:805)
    at akka.util.ReentrantGuard.withGuard(LockUtil.scala:15)
    at akka.actor.ActorSystemImpl$TerminationCallbacks.run(ActorSystem.scala:805)
    at akka.actor.ActorSystemImpl$$anonfun$terminationCallbacks$1.apply(ActorSystem.scala:639)
    at akka.actor.ActorSystemImpl$$anonfun$terminationCallbacks$1.apply(ActorSystem.scala:639)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:91)
    at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply(BatchingExecutor.scala:91)
    at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply(BatchingExecutor.scala:91)
    at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:72)
    at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:90)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
IvenZ commented 9 years ago

Du hast recht. Die Einträge waren wohl noch vorhanden. Ich habe auch keine weitere Lösung für das Problem gefunden. Aber ich glaube, dass wir die Evolutions auch missbrauchen und sie gar nicht für unser Vorhaben gedacht ist.

Wenn man mal nach Initial Data schaut findet man sowas hier: http://stackoverflow.com/questions/26934354/how-to-load-insert-initial-data-into-database-with-ebean-in-play-framework https://www.playframework.com/documentation/2.2.x/JavaGuide3

Da werden diese Sachen dann in der Global gehandhabt. Das ist allerdings noch aus 2.2.x

Ab 2.4 wird mit DI die Global ganz vorsichtig deprecated und man soll andere Wege finden

If you are keen to use dependency injection, we are recommending that you move out of your GlobalSettings implementation class as much code as possible. Ideally, you should be able to refactor your code so that it is possible to eliminate your GlobalSettings class altogether.

http://stackoverflow.com/questions/31454857/playframework-2-4-globalsettings-onstart-deprecated https://www.playframework.com/documentation/2.4.2/GlobalSettings

fabiankirstein commented 9 years ago

Ich glaube nicht das wir das missbrauchen. Das ist doch für Datenbankmigration. Die Datenbank ändert sich und man führt ein Migrationsskript aus. Genau in dieser Reihenfolge. Man könnte mal folgendes probieren: In einem Model ein Feld hinzufügen und das dann mit einem Evloution-Skript auf einene Default-Wert setzen. Mal sehen in welcher reihenfolge das ausgeführt wird. Falls das gehen sollte, können wir wirklich unser Initzeug anders lösen.

IvenZ commented 9 years ago

Also ich verstehe das eben genau so

a way to track and organize your database schema evolutions

Wenn ich eine DB neu aufsetze, bzw ein Projekt welches mir aber Tabellen und co. erzeugt, findet in diesem Moment keine Evolution statt. Das Projekt hat ja den aktuellen DB Schema stand und es muss nix geändert werden. Erst wenn alles vorhanden ist und im Laufe der Entwicklung etwas am DB Schema geändert werden muss, dann ist es für mich eine Evolution.

Ist auch egal. Auf irgendeinem Weg müssen wir es erreichen. Deinen Vorschlag habe ich allerdings nicht ganz verstanden, soll dieses Feld ein Skript triggern? Dazu habe ich nämlich nix gefunden.

fabiankirstein commented 9 years ago

Nein. Du sollst die DB migrieren. Also ein Model ändern, z.B. ein Feld also eine Property hinzufügen. Gleichzeitig legst du ein Evolution Skript an, welches etwas in dieses neu Feld schreibt. Sollte wieder das Skript vor Hibernate ausgeführt werden, failed das natürlich.

IvenZ commented 8 years ago

Ich hab das hier noch mal getestet. Also es failed auch. Das Script wird vor Hibernate ausgeführt.

IvenZ commented 8 years ago

So, also meine heutigen Recherchen haben mich nur wieder auf den Weg wie im Kommentar vom 27.8 gebracht. Wir sollten die Global komplett refactoren und Initial Data wie von Play vorgeschlagen durch DI regeln lassen und das Zeugs an die Klassen selber hängen.

Im Moment ist es sowieso sehr unschön. Unserer "Startup"-Gruppen oder der Admin Account wird über die Global erstellt und die studycourse-Kurse übers Evolutions-Script.

Wenn sich in Zukunft was am DB Schema ändert, müssen wir die komplette Schemaänderung im Evo-Script mitgeben. Also wir lassen in diesem Fall nix von Hibernate generieren, sondern erzeugen die Tabelle oder Spalte im Script. Vielleicht nicht so fancy aber scheinbar geht es aktuell nicht anders. Ist mMn aber auch zu verschmerzen.

Wäre das Problem dann gelöst? Oder habe ich einen Anwendungsfall vergessen?

Werde mir als nächstes mal die Exception der Email-Triggerung angucken. Sieht ja wieder ganz danach aus, als würde es sich um ein bekanntes Problem handeln (kein EM mehr vorhanden und kann scheinbar auch nicht mehr erzeugt werden). Auch das kommt ja wieder aus der Global und müsste sowieso refactored werden. Vielleicht erledigt sich dann auch die Exception.

fabiankirstein commented 8 years ago

Ich denke du hast Recht wir haben keine Wahl. Ich habe aber nochmal auf Stack Overflow eine Bounty auf meine Frage erstellt. Vielleicht kommt noch was. Irgendwie ist das ja schon ein Bug in Play. Und insgesamt finde ich es krass, dass es bis heute keine ordentliche Migrationsunterstützung gibt in Hibernate. Dagegen is es purer Luxus mit Django zu entwickeln. Aber wie auch immer es gibt keine Lösung. Ich hatte in den letzten Wochen immer mal wieder auf Arbeit rumgefragt, ob es eine bessere Lösung gibt, als selber SQL zu schreiben. In jedem Fall wissen wir dann genau was wann passiert. Aber eine Sache: Du solltest die initiale Migration nicht selber machen, falls es Änderungen am Model gibt. Das muss Hibernate machen. Du weißt doch sonst garnicht welcher Hibernate Datentyp auf welchen SQL Datentyp gemappt wird und wie er am liebsten Contrains haben will. Ein ideales vorgehen sieht für mich so aus:

Alles klar?

IvenZ commented 8 years ago

Alles klar. Ich weiß jetzt auch ungefähr wie es geklingt die Global zu refactoren. Werde das die Tage mal ausprobieren und schauen, ob dann die Ex weg geht.

IvenZ commented 8 years ago

strage... im aktuellen Stand scheinen die Evo-Skripte wieder zu laufen. Hatte jetzt gar nicht so sehr drauf geachtet, aber wenn ich neu aufsetze scheint es keine Probleme zu geben.

fabiankirstein commented 8 years ago

kann doch garnicht sein. du hast bestimmt nen falschen branch. :)

IvenZ commented 8 years ago

So Fabi, ich bin jetzt an einem Punkt, an dem mir unsere Architektur ein bisschen auf die Füße fällt (glaube ich zumindest).

Es besteht das Problem, dass alle Eingaben die durch eine Form passieren (so ziemlich alle) nicht DI tauglich sind. Konkret: z.B. unser Account Model injected ab jetzt den ElasticsearchService (immer wenn ein Account angelegt oder geupdated wird, soll die Änderung ja auch im ES passieren). Dafür muss, wie du weißt, aber bereits das Account Objekt durch die Anwendung injected sein. Das ist NICHT der Fall, wenn wir Daten aus einer Form auslesen (filledForm.get()). Eine accountForm erstellt sich sein ganz eigenes Account Objekt. In welchem ein ES-Objekt natürlich nicht injected ist.

Das zieht sich so durch die ganze Anwendung (Gruppe/Post erstellen/beitreten/editieren usw)

Bei diesem Problem führen mehrere Wege nach Rom. Doch bevor ich einen beschreite, wollte ich das mit dir mal abstimmen.

fabiankirstein commented 8 years ago

Ich finde ja die Form-Sache in Play ist eine der besten Dinge an dem Framework. Wir sollten das nicht anrühren. Also eher Model und Model-Methoden trennen oder? Was hättest du den für eine Lösung.

IvenZ commented 8 years ago

z.B. ne DAO-Klasse würde uns an dieser Stelle ein bisschen helfen. Sie kann im Controller injected werden, injected selber ne ES Instanz und nimmt dann einfach nur das entsprechende Model entgegen.

fabiankirstein commented 8 years ago

Lass uns die woche mal skypen dazu. Aber eine Frage: Wie machst du das grundsätzlich mit DI und Models. Ich hatte das Problem, dass ja Hibernate die Instanzen erstellt und da hat DI auch nicht funktioniert?

IvenZ commented 8 years ago

An welchen Stellen genau? Die Controller habe ich kaum angefasst. Die bisherigen Änderungen betrafen nur das Anpassen der Global

fabiankirstein commented 8 years ago

In allen Models! Hat bei mir nie geklappt.

IvenZ commented 8 years ago

Ich glaube es ist vollbracht. Würde den aktuellen Stand nun als arbeitsfähig attestieren. Vielleicht gibt es hier oder da noch einen Bug. Konnte ich mit mein bissel rumgespiele aber aktuell nicht ausmachen.

Wenn du möchtest, kannst du dir das Ding nun als Socia Basis nehmen.

Ich werde jetzt vorsichtig anfangen das Ding mit dem aktuellen Master zu mergen.

fabiankirstein commented 8 years ago

Ich werde das heute Abend oder morgen mal testen. Danke!!!

IvenZ commented 8 years ago

Habe noch ein paar Sachen gefunden und behoben.

fabiankirstein commented 8 years ago

Ich bekomme den Branch nicht zum laufen. Muss ich noch was beachten. Ich hab ne komplett neue Datenbank angelegt und alles wie immer gebaut. Er bleibt einfach bei diesem Stand komplett stehen:

[warn] application - Logger configuration in conf files is deprecated and has no effect. Use a logback configuration file instead.
[info] application - Creating Pool for datasource 'default'
[info] p.a.d.HikariCPConnectionPool - datasource [default] bound to JNDI as DefaultDS
[info] p.a.d.DefaultDBApi - Database [default] connected at jdbc:postgresql://localhost/htwplus
log4j:WARN No appenders could be found for logger (org.elasticsearch.plugins).
log4j:WARN Please initialize the log4j system properly.

Es passiert einfach nichts. Im Browser wartet er ewig auf eine Antwort. Elastic sagt das:

[2016-01-16 12:56:31,331][WARN ][transport.netty          ] [La Nuit] Message not fully read (request) for [0] and action [cluster:monitor/nodes/liveness], resetting

Eine Idee?

IvenZ commented 8 years ago

Hm, also diesen Fehler habe ich nicht, aber dafür einen Anderen. Ich versuche das mal morgen zu berichtigen.

Ansonsten: aktuellen ES Server? alle Änderungen aus der app.sample.conf übernommen?

fabiankirstein commented 8 years ago

Hab die sample komplett neu kopiert. ES hab ich noch 1.4 Was soll ich denn nehmen?

IvenZ commented 8 years ago

2.1 ist meine Aktuelle

fabiankirstein commented 8 years ago

ok. ich teste später nochmal mit der version.

IvenZ commented 8 years ago

dann zieh dir noch mal meinen fix und dann müsste es auch durchlaufen ;-)

fabiankirstein commented 8 years ago

Läuft! Lag echt an der Elasticsearch Version.

fabiankirstein commented 8 years ago

@IvenZ Wird das gemerged?

IvenZ commented 8 years ago

Ja, am Wochenende :-)

fabiankirstein commented 8 years ago

Ich dachte es wäre schon?