Hi,
I presume that when you broadcast from your EJB it is outside the
scope of an HTTP request?
Currently support for Viewable, that references an absolute view,
requires that an HTTP request be in scope (note that you will also get
an error if the view is not absolute and you do not declare a
resolving class because Jersey will need to look up the last matching
resource class to be used as the resolving class).
The current TemplateProcessor interface is too restrictive, in a
number of ways, thus i had to add a property on the request to declare
further state. To fix this properly will require changes to
TemplateProcessor or introducing a new interface TemplateProcessor2 to
avoid breaking backwards compatibility. So i think in this case you
can consider it a bug for absolute views :-)
As a hacky work around you can add your own implementation of
ViewableMessageBodyWriter that overrides Jersey to say trap the
exception and ignore when the HttpContext reference is accessed, see
below.
Paul.
public final class ViewableMessageBodyWriter implements
MessageBodyWriter<Viewable> {
@Context HttpContext hc;
@Context UriInfo ui;
@Context TemplateContext tc;
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return Viewable.class.isAssignableFrom(type);
}
public void writeTo(Viewable v,
Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object>
httpHeaders,
OutputStream entityStream) throws IOException {
final ResolvedViewable rv = resolve(v);
if (rv == null)
throw new IOException("The template name, " +
v.getTemplateName() +
", could not be resolved to a fully qualified
template name");
try {
hc.getProperties().put("com.sun.jersey.spi.template.ResolvedViewable",
rv);
} catch (IllegalStateException ex) {
// ignore if request not in scope
}
rv.writeTo(entityStream);
}
private ResolvedViewable resolve(Viewable v) {
if (v instanceof ResolvedViewable) {
return (ResolvedViewable)v;
} else {
return tc.resolveViewable(v, ui);
}
}
public long getSize(Viewable t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
}
On Dec 17, 2009, at 11:36 AM, Ori Dagan wrote:
> Hi,
>
> I'm using Atmosphere(0.4.1)-Jersey(1.1.4.1) on glassfish v3.
> I have a scenario where users subscribe for an event through Jersey
> and the events are broadcaster from an EJB module in the same
> application.
> The code is somethig like that:
>
> In WAR:
>
> @GET
> @Suspend
> @Path("subscribe/{topic: scene-stream}")
> @Produces({"text/html;charset=ISO-8859-1"})
> public Broadcastable subscibe(@PathParam("topic") Broadcaster topic)
> {
> return new Broadcastable("", topic);
> }
>
> and in EJB:
>
> {
> ...
> Broadcaster broadcaster = BroadcasterLookup.lookup("scene-
> stream");
> Map<String, Object> model = new HashMap<String, Object>();
> model.put("scene", sceneEntity);
> Viewable viewable = new Viewable( "/scene-info.ftl", model);
> Future f = broadcaster.broadcast(viewable);
> }
>
> When broadcastin I'm getting this exception:
>
> [#|2009-12-16T18:15:00.098+0200|WARNING|glassfishv3.0|Atmosphere|
> _ThreadID=34;_ThreadName=Thread-1;|
> java.lang.IllegalStateException
> at
> com
> .sun
> .jersey
> .server
> .impl
> .ThreadLocalHttpContext.getProperties(ThreadLocalHttpContext.java:95)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .template
> .ViewableMessageBodyWriter.writeTo(ViewableMessageBodyWriter.java:80)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .template
> .ViewableMessageBodyWriter.writeTo(ViewableMessageBodyWriter.java:58)
> at
> com
> .sun
> .jersey.spi.container.ContainerResponse.write(ContainerResponse.java:
> 266)
> at
> org
> .atmosphere
> .jersey.JerseyBroadcaster.broadcast(JerseyBroadcaster.java:193)
> at org.atmosphere.jersey.JerseyBroadcaster.access
> $400(JerseyBroadcaster.java:66)
> at org.atmosphere.jersey.JerseyBroadcaster
> $1.run(JerseyBroadcaster.java:175)
> at java.util.concurrent.Executors
> $RunnableAdapter.call(Executors.java:441)
> at java.util.concurrent.FutureTask
> $Sync.innerRun(FutureTask.java:303)
> at java.util.concurrent.FutureTask.run(FutureTask.java:138)
> at java.util.concurrent.ThreadPoolExecutor
> $Worker.runTask(ThreadPoolExecutor.java:886)
> at java.util.concurrent.ThreadPoolExecutor
> $Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:619)
>
>
> Is this a bug or broadcasting a Viewable from outside the web
> container is just not possible?
>
> Thanks