We are using Vaadin 23 (23.0.9) with vaadin-cdi (14.0.0) and are having problems with conditional observers in #RouteScoped components (like it is described in the tutorial):
#RouteScoped
public class ScopedComponent extends Div {
private void onMessage(
#Observes(notifyObserver = IF_EXISTS)
MessageEvent message) {
setText(message.getText());
}
}
We are running on Tomcat 9 and use Weld (3.1.9.Final) as our CDI implementation.
Our current problem is that we get the following exception when firing an event that is observed in a #RouteScoped component:
java.lang.IllegalStateException: Route owner 'class XXX' instance is not available in the active navigation components chain: the scope defined by the bean 'YYY' doesn't exist.
We believe that the problem are the changes implemented in Vaadin CDI 13.0.0 (https://github.com/vaadin/cdi/releases/tag/13.0.0):
Trying to use #RouteScope when there is no active route component present is not allowed.
In the Weld implementation we are using, the method getReceiverIfExists calls the method getContextualStorage() in class RouteScopedContext. And getReceiverIfExists is called before the reception of the observer is considered. Therefore all classes that have an observer on the event are trying to be received and since not all #RouteScoped classes are in the current navigation chain, the above mentioned error is thrown.
Object receiver = getReceiverIfExists(null); //this is where the exception is thrown
if (receiver == null && reception != Reception.IF_EXISTS) {
// creational context is created only if we need it for obtaining receiver
// ObserverInvocationStrategy takes care of creating CC for parameters, if needed
creationalContext = beanManager.createCreationalContext(declaringBean);
receiver = getReceiverIfExists(creationalContext);
}
if (receiver != null) {
sendEvent(event, receiver, creationalContext);
}
We are not quite sure, what we are doing wrong or what we could do differently. Are we using the correct versions vaadin-cdi and Weld?
This is currently a bug in vaadin-cdi (version 14.0.0): https://github.com/vaadin/cdi/issues/390
A bugfix is already merged: https://github.com/vaadin/cdi/pull/393
Related
I need to extend the listener class of audit-logging plugin, in order to provide different functionality on some scenarios.
For that purpose I have created this class:
class CustomAuditLogListener extends AuditLogListener{
public CustomAuditLogListener(Datastore datastore) {
super(datastore)
}
#Override
protected void onPreUpdate(event) {
. . .
}
}
Now, in order for the plugin to use this class instead of the default
AuditLogListener, within Bootstrap.groovy I try to remove AuditLogListener from the application listeners, and add the custom listener:
def applicationContext = servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
log.debug("Application listeners - PRE")
log.debug(applicationContext.getApplicationListeners())
// Remove all the listeners registered by the audit plugin.
applicationContext.getApplicationListeners.each { listener ->
if (listener.class == AuditLogListener.class) {
servletContext.getApplicationListeners.remove(listener)
log.debug("AuditLogListener removed ")
}
}
grailsApplication.mainContext.eventTriggeringInterceptor.datastores.each { key, datastore ->
// Don't register the listener if we are disabled
if (!grailsApplication.config.auditLog.disabled && !datastore.config.auditLog.disabled) {
def listener = new CustomAuditLogListener(datastore)
listener.with {
// some options
}
applicationContext.addApplicationListener(listener)
log.debug("Add new listener CustomAuditLogListener")
}
}
log.debug("Application listeners -POST")
log.debug(applicationContext.getApplicationListeners())
Application listeners - PRE returns empty list
Add new Listener CustomAudtilogListener is logged
Application Listeners - POST returns empty list
The way I register my listener is copied from the way the plugin registers the listener, seen in this class
To sum, what I need is replacing AuditLogListener, with my own CustomAuditLogListener. Currently the above process is not working. Any suggestions?
Hey sorry but the post does seem a little confusing, although I think I understand
I need to extend the listener class of audit-logging plugin.
Now, in order for the plugin to use this class instead of the default
AuditLogListener,
so you are trying to override the auditLogListener.
Your problem maybe that you are not declaring it as an override in your conf/spring/resources.groovy.
I have done a similar thing for a class rather than listener here:
https://github.com/vahidhedayati/testwschat/blob/master/test/unit/anythingbut/grails/plugin/wschat/MyOverrideServiceSpec.groovy
https://github.com/vahidhedayati/testwschat/blob/master/grails-app/conf/spring/resources.groovy
and something similar here:
grails kickstart plugin KickstartFilters how to prevent password information on logs
basically once you declare your bean
yourAppFilters(KickstartFilters)
This then tricks your grails-app and any plugins that maybe referring to KickstartFilters to now refer to yourAppFilters as the replacement
Try a bean like this: (ctrl shift o) to pull in CustomAuditLogListener
AuditLogListener(CustomAuditLogListener){
grailsApplication = ref('grailsApplication')
}
Using JSF 2 on JBoss AS 7
Getting the following error:
07:36:39,579 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/172.20.91.126:12580-16)
Error Rendering View[/views/afgarendesok.xhtml]:
com.sun.faces.mgbean.ManagedBeanCreationException:
Unable to set property searchManager for managed bean afgArendeBacking
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
The searchManager property is defined in the AfgArendeBacking class as:
#ManagedProperty(value="#{afgArendeSokManager}")
private AfgArendeSokManager searchManager;
#Override
public AfgArendeSokManager getSearchManager() {
return searchManager;
}
public void setSearchManager(AfgArendeSokManager searchManager) {
this.searchManager = searchManager;
}
The AfgArendeSokManager is a #ManagedBean that is #SessionScoped.
Two things I don't get. One is why the error shuts down all usage of JSF not just for the session producing the error. The error seems to appear after non-usage both below the default session timeout and beyond. The other odd this is that a null pointer exception at line 606 in the BakedBeanProperty has to be the one the writeMethod variable. That variable is created via the PropertyDescriptor.getWriteMethod() call. This should have bombed earlier when creating baked bean (i.e. bakeBeanProperty method).
Any ideas how to debug? The property "searchManager" is resolved correctly since we can use the JSF views normally (both the getter/setter exist).
The search manager is our session scratch pad for propagating stuff between view and request scoped backing beans.
The article explains the issue of using reflection to access methods with covariant return types (see here: https://dzone.com/articles/covariant-return-type-abyssal). The article relates to Java 6 but the background information is very useful.
The issue you're facing and that hit us just this week (using Java 1.7.0_40) is not one of EL but of the java.beans.Introspector.
I am new to Android development with Xamarin.Android and I would like to understand how to have the next issue fixed.
Sometimes after restoring my Android application from background I was facing the next error:
Unable to find the default constructor on type MainMenuFragment. The MainMenuFragment is used by the application NavigationDrawerActivity to allow users to switch between different Fragments inside the app.
In order to solve it, I added a default constructor to the MainMenuFragment as described inside the next links:
Xamarin Limitations - 2.1. Missing constructors
Added a default constructor, should fix the issue.
public class MainMenuFragment : DialogFragment
{
readonly NavigationDrawerActivity navigationDrawer;
#region Constructors
public MainMenuFragment () {} // Default constructor...
public MainMenuFragment (NavigationDrawerActivity navigationDrawer, IMenuType launchMenu = null)
{
if (navigationDrawer == null)
throw new ArgumentNullException ("navigationDrawer");
this.navigationDrawer = navigationDrawer;
...
Fragment UpdateTopFragmentForCurrentMenu (Fragment newMenuRootFragment = null)
{
Fragment currentMenuRootFragment = navigationDrawer.CurrentFragment; // issued line.
But now sometime in the future, the MainMenuFragment gets initialized using its default constructor and at the first time it tries to access its navigationDrawer it throws a System.NullReferenceException:
System.NullReferenceException: Object reference not set to an instance of an object
at MainMenuFragment.UpdateTopFragmentForCurrentMenu (Android.App.Fragment) <0x00018>
at MainMenuFragment.OpenMenu (IMenuType,bool) <0x0006b>
at MainMenuFragment.OnCreate (Android.OS.Bundle) <0x00053>
at Android.App.Fragment.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x0005b>
at (wrapper dynamic-method) object.3919a6ec-60c1-49fd-b101-86191363dc45 (intptr,intptr,intptr) <0x00043>
How can I have a default constructor implemented without facing this null reference exception?
You're programming like a C# developer, thats what the problem is :) I faced these same hurdles learning monodroid.
Take a look at the examples out there, in java, you'll see almost all the time they initialize using a static method like object.NewInstance() which returns object. This is how they initialize their views/receivers/fragments. At that point they populate the Arguments property and store that in the fragment. You need to remove all your constructors EXCEPT the empty ones and use arguments to pass your data around. If you try to do this using constructors and regular oo concepts you'll be in for a world of hurt. Arguments.putExtra and all those methods are there. It makes things a little verbose but once you get the hang of it you'll start creating some helper methods etc.
Once you get that sorted, you'll need to figure out if you need to recreate your fragments everytime the activity is resumed and if not, mark them as RetainInstance = true as well as get them onto a fragmentmanager which will help you retain all your state.
If you haven't built on android before it's weird and certainly not what I expected. But it's reeaaallly cool, much more awesome than I expected too. And same with Xamarin.
Great similar question: Best practice for instantiating a new Android Fragment
I'm in the process of migrating a struts 2.2.3.1 portlet application (jsr168) to the new version, 2.3.3. For the most part everything still works the same, but there was one obvious problem.
I'm using a package.properties resource bundle for things like titles and labels in my jsp's. When I first hit an action, the messages are retrieved from the resource bundle and displayed as expected. When I make a second request to an action though, the message keys are displayed, which typically means the resource was not found.
(The main difference between the first time hitting an action and any subsequent request seems to be that on the first request ONLY the event portlet phase is processed, and not the render portlet phase. Any follow up requests both phases are used.)
It took me quite a while to figure out what is going on, but here is roughly what's happening:
I started out by stepping through org.apache.struts2.components.Text. This class is used when a struts text tag is encountered in a jsp.
The end() method uses the static getText() method from the TextProviderHelper. This is where I found the root of the problem:
for (Object o : stack.getRoot()) {
if (o instanceof TextProvider) {
tp = (TextProvider) o;
msg = tp.getText(key, null, args, stack);
break;
}
}
The above code iterates through the value stack until it finds a TextProvider. Because ActionSupport implements TextProvider, and because struts tries to put the action at or near the top of the stack, the action is usually the provider.
Here's the objects in the value stack at different times for both versions:
Version 2.2.3.1
First request value stack
-->TestPortletAction
DefaultTextProvider
Second request value stack
-->TestPortletAction
DefaultTextProvider
DirectRenderFromEventAction
DefaultTextProvider
Version 2.3.3
First request value stack
-->TestPortletAction
DefaultTextProvider
Second request value stack
DirectRenderFromEventAction
DefaultTextProvider
-->TestPortletAction
DefaultTextProvider
So, for some reason, in the new version the action class is not at the top of the stack after the render phase is processed. This means that the TextProviderHelper uses the DefaultTextProvider, which does try to locate the resource bundle... but is never successful in doing so.
I did some investigation into how that DefaultTextProvider gets pushed into the stack:
Jsr168Dispatcher.serviceAction() makes the call to the ActionProxyFactory to create the action proxy. Just before returning the proxy a call is made to prepare(), which in turn makes a call to the DefaultActionInvocation's init method. The init calls createContextMap() which creates the stack
stack = valueStackFactory.createValueStack();
The constructor used:
protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticAccess) {
setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticAccess);
push(prov);
}
Aaaaaand that's about as far as I have got on the problem so far. The questions that remain are:
How and where does the second DefaultTextProvider get pushed onto the stack? (And is there a real reason to have two of them?)
How and where does the DirectRenderFromEventAction get pushed onto the stack?
What change in the new version is causing this?
Is this a bug or intended behavior?
A possible solution (that does fix it) is to explicitly call the action's getText method using ognl, but I don't see this as ideal, and it does mean changing a bunch of jsp files.
<s:property value = "%{getText('some.key')}"/>
A sample project that demonstrates the problem can be found here (It's a maven project):
http://new-value-stack-order.googlecode.com/svn
I'm using tomcat 6.0.25 with pluto 1.1.7 as my development environment.
Figured it out. The answer lies in the PortletStateInterceptor
2.2.3.1
#SuppressWarnings("unchecked")
private void restoreStack(ActionInvocation invocation) {
RenderRequest request = (RenderRequest) invocation.getInvocationContext().get(REQUEST);
if (StringUtils.isNotEmpty(request.getParameter(EVENT_ACTION))) {
if(!isProperPrg(invocation)) {
if (LOG.isDebugEnabled()) LOG.debug("Restoring value stack from event phase");
ValueStack oldStack = (ValueStack) invocation.getInvocationContext().getSession().get(
STACK_FROM_EVENT_PHASE);
if (oldStack != null) {
CompoundRoot oldRoot = oldStack.getRoot();
ValueStack currentStack = invocation.getStack();
CompoundRoot root = currentStack.getRoot();
root.addAll(0, oldRoot);
if (LOG.isDebugEnabled()) LOG.debug("Restored stack");
}
}
else {
if (LOG.isDebugEnabled()) LOG.debug("Won't restore stack from event phase since it's a proper PRG request");
}
}
}
2.3.3
#SuppressWarnings("unchecked")
private void restoreStack(ActionInvocation invocation) {
RenderRequest request = (RenderRequest) invocation.getInvocationContext().get(REQUEST);
if (StringUtils.isNotEmpty(request.getParameter(EVENT_ACTION))) {
if(!isProperPrg(invocation)) {
if (LOG.isDebugEnabled()) LOG.debug("Restoring value stack from event phase");
ValueStack oldStack = (ValueStack) invocation.getInvocationContext().getSession().get(
STACK_FROM_EVENT_PHASE);
if (oldStack != null) {
CompoundRoot oldRoot = oldStack.getRoot();
ValueStack currentStack = invocation.getStack();
CompoundRoot root = currentStack.getRoot();
root.addAll(oldRoot);
if (LOG.isDebugEnabled()) LOG.debug("Restored stack");
}
}
else {
if (LOG.isDebugEnabled()) LOG.debug("Won't restore stack from event phase since it's a proper PRG request");
}
}
}
Note the root.addAll(). In the old version it adds the old stack to the beginning of the current stack. In the new version it adds it to the end.
This was actually an old bug fixed in 2.1.3. Creating a new issue in Jira.
An application is using JBoss 4.2.2, and I have found it necessary to call listThreadDump(), and I expect it is in ServerInfo.
I am thinking the jar I need to find this information is jboss-jmx.jar.
So, how do I programmatically duplicate what is done by calling something similar to http://localhost:8080/jmx-console/HtmlAdaptor?action=invokeOpByName&name=jboss.system:type=ServerInfo&methodName=listThreadDump?
This is how I have accessed the ServerInfo MBean. I'm using JBoss AS 5.1, but this method should be the same.
To call listThreadDump(), you can invoke() the method on the ServerInfo MBean using an MBeanServer instance.
Additionally, you can access attributes of MBeans using the same MBeanServer.
Sample code:
// imports
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.mx.util.MBeanServerLocator;
try {
MBeanServer server = MBeanServerLocator.locate();
ObjectName name = new ObjectName("jboss.system:type=ServerInfo");
// invoke the listThreadDump method and capture its output
String threadDumpHtml = (String) server.invoke(name, "listThreadDump", null, null);
// access a simple attribute of the ServerInfo object
String jvmName = (String) server.getAttribute(name, "JavaVMName");
} catch (Exception e) {
// Ideally catch the 3 exact exceptions
}
Finally, I find it handy when MBeans expose an 'instance' attribute, so you can then access the object directly (CastToType) server.getAttribute(name, "instance") instead of always going through the MBeanServer. For example, when using JMS, the ServerPeer instance is nice to have as you can get message counters on your queues and topic subscribers.