Yesterday, while adding the FITC Demo I was able to verify that there is some cloberring happening within the shared Spring beans, meaning that when one war loads it will overwrite the beans that share the same name and that were previously instantiated by the Spring context loader. I'll ry to fix this sometime soon. In the meantime I've also added the latest ear to the blog page. Keep in mind that, because of this clobering, having multiple war being deployed through the ear might not work.
It looks like an issue is with the beanRefContext.xml. You do not have to add the application's *-web.xml to the beanRefContext. It's a special context that isn't supposed to be handled by Spring, but by Red5 itself. In fact, none of the files are necessary except for logback-oflaDemo.xml and oflaDemo-web.xml. Once I removed everything else, the oflaDemo gets the streams from the proper directory every time.
I haven't tested it yet but I'm going to guess that's why you were also having problems deploying multiple wars.
EDIT: Nevermind, this broke things.
Ok, I am able to get multiple demos running, it just took some tweaks.
1) Delete fitcDemo-web.xml and oflaDemo-web.xml from the red5.war/WEB-INF/classes directory.
2) Add this to web.xml in fitcDemo.war/WEB-INF/classes:
3) In the beanRefContext.xml, both demos need to have defaultContext.xml, red5-core.xml and red5-common.xml. You do NOT want the oflaDemo-web.xml and fitcDemo-web.xml in there. Those files get loaded by the red5 war loader.
After that, I was able ot have both demos running no problem.
Thanks for the hints. I believe that I have found the way to make everything play nicely together. I've simplified it quite a lot to. Basically, the wars (other than the Red5 one) do not need the beanRefContext.xml for anything. All they need is to load the necessary *-web.xml files. In the end, and because the Spring context seems to be shared among wars, one single load of defaultContext.xml, red5-common.xml and red5-core.xml should suffice since they reconfigure the same beans.
The shared object demo is now broken, but I'm convinced that if I put it on it's own war that it will play along with the other wars.
Note: If the first deployment fails, cleanly stop the server and start it again. It seems that it doesn't always clean the cache or deploys the wars in the same order (not sure yet which).
I downloaded your ear, and I had some problem with deployments, as it seemed like it did not register the context first. I found a solution though that makes it so you are guaranteed to have default.context available before any WARs deployed.
I created a jar called red5-context.jar in /lib and simply put the following files from red5.war/WEB-INF/classes:
The beanRefContext.xml in the red5-context.jar I removed the root-web.xml, vod-web.xml and installer-web.xml. This causes the default.context bean to be instantiated before the first war deploys.
In the red5.war/WEB-INF/classes/beanRefContext.xml I removed the defaultContext.xml, red5-common.xml, red5-core.xml entries and deleted those files.
Now the default.context is available at startup with no problems.
Also, yes, the spring default.context that red5 uses is shared, but it does it in a strange manner. It's actually doing it via the code in org.red5.server.war.WarLoaderServlet. There's a line of code that looks like this:
I'm not sure how I feel about this, because it makes it hard to chain contexts from shared beans in your ear. For example, if I wanted to put my DAO and hibernate session in a shared context between applications, if I want to use red5 then default.context has to be at the highest level (all my future contexts will have to inherit from that), so it makes it difficult to create a clean hierarchy in your applications. I think I may end up changing that servlet to make my life easier and separating out some logic.
Basically, my goal is to have something like this:
DAO Beans Context/Hibernate -> Red5 Context -> ApplicationA.war
DAO Beans Context/Hibernate -> ApplicationB.war
The DAO Beans Context/Hibernate would be shared across the .ear to all the .wars, but the way red5 registers that context it isn't possible right now, so it has to be:
Red5 Context -> DAO Beans Context/Hibernate -> ApplicationA.war
Red5 Context -> DAO Beans Context/Hibernate -> ApplicationB.war
I guess I'm nitpicking but it's something I'd like to solve.
Thanks, the red5-context.jar works just fine with most examples. Unfortunately, there's something still foggy since the VOD example (the initial video from the red5 home page) does not work this way.
Regarding the hard-coded "default.context" loading, yes, I agree with you but I'm not sure yet why they did it like this. This is obviously not optimal for enterprise level applications. The thing that comes to mind might be due to some sort of limitation of the current implementation of AMF/RTMP listeners (port usage shared among apps, etc).
Regarding the logging issues, yeah... not there yet mate! I only have time to work on this a couple of hours a day after my children is put to bed. Still, I'll try to have a look into it later today.
I've moved the VOD and the SOSample into their own ears and everything seems to be working just fine now with the trick of having the initial default context in the red5-context.jar has you've mentioned. It's now available for download through my blog.
I'll try to look into the logging issue since that is in-fact very annoying. I'm running JBoss through Eclipse and that kinda helps to manage it. Still, for production environments one needs to be able to disable it or redirect it somewhere else. I believe that we might be able to configure JBoss logging to filter and prevent from logging everything "org.red5.*" and "o.r.s.*" to the stdout.
Just added both Audio and Video Trancoders Xugger based demos. Everything seems to be working fine.
Another note of interest, is that it might be possible (not tested yet) to force the wars to be loaded in order of apperance in application.xml file. For that to happen we only need to add the tag:
If this is true, then we might not require to specially package the loading of the default context on its own specific jar.
One thing I've noticed about logging is it looks like it's actually going through two logging systems, for example:
17:22:25,320 INFO [stdout] (MSC service thread 1-1) 17:22:25.319 [MSC service thread 1-1] DEBUG o.r.s.persistence.FilePersistence - Object path: /default
You can see there's two timestamps, the format is actually: [timetamp] [loglevel] [source] [thread] [message]
However, in this case, [message] is another log format. I can change the log output somewhat if I modify logging.properties and standalone.xml in standalone/configuration. However, it looks like red5 is picking up a logging system from somewhere else and outputting it to stdout. One temporary solution is to raise the debug level for the console in standalone.xml, but this isn't a completely acceptable solution because the application shouldn't be writing to stdout in the first place.
Hopefully I can figure this out today, I think it's the last thing that is driving me nuts about this.
Looks like this is a problem with logback. I'm not sure what it is yet, but if I remove the logback libs, and add the slf4j-log4j and log4j libs, it parses a log4j.properties file correctly and it no longer dumps everything to standard out. It's still appending the other log information from the jboss configuration, but at least it doesn't go to the console all the time.
I'm still not clear on what system jboss as7 uses as logging, but I'm at least pointed in the right direction.
And I figured it out . Looks like there's some trickery you can do with JBoss AS7 in regards to modules. JBoss uses it's own logging system (jboss-logmanager) and luckily for us, they package a slf4j bridge for it. However, to let your EAR load the modules, you have to create a jboss-deployment-structure.xml file and tell it to load modules. If you look in $JBOSS_HOME/modules you will see a directory structure of modules, and each one will have a module.xml. If you look in the module.xml, you will see the moduel has a name value. Using that, you can import these modules into yuor application.
So here is what I did to get sane logging:
I created in META-INF of the EAR, this jboss-deployment-structure.xml:
<module name="org.slf4j" />
Then, in red5.ear/lib, I deleted:
Because we are now importing them from the jboss module directory.
And I also deleted:
So that slf4j does not try to use logback as it's logging system. The org.slf4j.impl module from jboss provides the slf4j interface for jboss' own logging system. Once this is done, your applications will now obey the configuration you set in standalone.xml, which you can see in around the section starting with <subsystem xmlns="urn:jboss:domain:logging:1.0">.
I'm not sure how to get the logging configuration per application yet, but that's my final task. Definitely nice to not be bombarded with logging information, though.
I just got confirmation from the #jboss IRC channel that you can not have per-deployment configuration of logs in 7.0 if you use the jboss-logmanager mechanism. This means that to configure logging you need to do it in either standalone.xml or use the JBoss administration console. I was told it should be ready in 7.1.
If you truly need per-deployment logging configuration, you can use the log4j bindings for slf4j, which worked for me. You still get the strange "double log formatting" but you can at least write it to a file and control the logging level instead of going to the console.
I also had a problem loading the xugger demos, but that's OK, but I think everything is set now for me.