[JBoss JIRA] (REMJMX-97) Optimise addNotificationListener so no handback needs to be sent.
by Darran Lofthouse (JIRA)
Darran Lofthouse created REMJMX-97:
--------------------------------------
Summary: Optimise addNotificationListener so no handback needs to be sent.
Key: REMJMX-97
URL: https://issues.jboss.org/browse/REMJMX-97
Project: Remoting JMX
Issue Type: Sub-task
Components: Connection
Reporter: Darran Lofthouse
Assignee: Darran Lofthouse
Fix For: 2.0.2.CR1
The following method call has been updated as a result of REMJMX-91 so null is sent for the handback - this is to retain compatibility with existing installations currently using version 2 of the protocol.
{code}
public void addNotificationListener(final ObjectName name, NotificationListener listener,
final NotificationFilter filter, final Object handback) throws InstanceNotFoundException, IOException {
{code}
In version 3 we can drop sending the handle.
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months
[JBoss JIRA] (REMJMX-96) Create version 3 of the protocol
by Darran Lofthouse (JIRA)
Darran Lofthouse created REMJMX-96:
--------------------------------------
Summary: Create version 3 of the protocol
Key: REMJMX-96
URL: https://issues.jboss.org/browse/REMJMX-96
Project: Remoting JMX
Issue Type: Task
Reporter: Darran Lofthouse
Assignee: Darran Lofthouse
Fix For: 2.0.2.CR1
This is not a commitment to add version 3, that will be determined by the impact of other changes made.
This is more a case of tracking the changes that will need to be made in version 3 if it ever exists.
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months
[JBoss JIRA] (REMJMX-91) AddNotificationListener is serializing the handback object to the server -- causing ClassNotFoundExceptions.
by Darran Lofthouse (JIRA)
[ https://issues.jboss.org/browse/REMJMX-91?page=com.atlassian.jira.plugin.... ]
Darran Lofthouse commented on REMJMX-91:
----------------------------------------
The reason the handback was sent was consistency with the following method: -
{code}
void addNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException,
IOException
{code}
i.e. this method does need the handback sent to the server as it needs to be passed to another MBean.
But in the case identified here the NotificationListener is not sent to the server so we can also optimise and avoid sending the handle, should be a fairly trivial change without breaking backwards compatibility to stop sending the handle.
Note: Although this issue is addressing an error experienced on the server it is actually only the client side that needs the fix.
> AddNotificationListener is serializing the handback object to the server -- causing ClassNotFoundExceptions.
> ------------------------------------------------------------------------------------------------------------
>
> Key: REMJMX-91
> URL: https://issues.jboss.org/browse/REMJMX-91
> Project: Remoting JMX
> Issue Type: Bug
> Components: Notifications
> Affects Versions: 2.0.1.CR1
> Reporter: Bryan Varner
> Assignee: Darran Lofthouse
> Fix For: 2.0.1.CR2
>
>
> I have a client using a handback object when events are received from remote JMX servers.
> The handback is a local object instance used in the client, and should be operated on as part of handling specific types of notifications. Rather than scoping this thing in my code all over the place, it was much easier to include it as a handback.
> This works _perfectly_ with the Oracle RMI client. When I try to use this code against JBoss remoting servers, I get (burried) ClassNotFound Exceptions referencing the name of my class.
> It appears that ClientConnection is sending serialized copies of the handback object to the server when a notificationListener is added... but why?
> https://github.com/jbossas/remoting-jmx/blob/master/src/main/java/org/jbo...
> Shouldn't the handback be local to the client?
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months
[JBoss JIRA] (WFLY-3962) onComplete for async listeners not always called
by John Sanda (JIRA)
[ https://issues.jboss.org/browse/WFLY-3962?page=com.atlassian.jira.plugin.... ]
John Sanda commented on WFLY-3962:
----------------------------------
We hit the issue again with 9.0.0.Beta1. Here is the exception we see,
{noformat}
2015-03-26 07:09:00,535 SEVERE [com.google.common.util.concurrent.ExecutionList] (MetricsThreadPool-3) RuntimeException while executing runnable com.google.common.util.concurrent.Futures$4@7d226165 with executor com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService@791dea19: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429) [rt.jar:1.8.0_20]
at java.util.HashMap$KeyIterator.next(HashMap.java:1453) [rt.jar:1.8.0_20]
at io.undertow.servlet.util.IteratorEnumeration.nextElement(IteratorEnumeration.java:44) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at org.jboss.weld.util.collections.EnumerationList.<init>(EnumerationList.java:42) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.context.beanstore.http.RequestBeanStore.getAttributeNames(RequestBeanStore.java:48) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.context.beanstore.AttributeBeanStore.getPrefixedAttributeNames(AttributeBeanStore.java:198) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.context.beanstore.AttributeBeanStore.attach(AttributeBeanStore.java:95) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.context.http.HttpRequestContextImpl.associate(HttpRequestContextImpl.java:57) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.context.http.HttpRequestContextImpl.associate(HttpRequestContextImpl.java:38) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.servlet.HttpContextLifecycle.requestInitialized(HttpContextLifecycle.java:214) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.weld.servlet.WeldInitialListener.requestInitialized(WeldInitialListener.java:160) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at io.undertow.servlet.core.ApplicationListeners.requestInitialized(ApplicationListeners.java:216) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.spec.AsyncContextImpl.setupRequestContext(AsyncContextImpl.java:681) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.spec.AsyncContextImpl.onAsyncComplete(AsyncContextImpl.java:591) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.spec.AsyncContextImpl.complete(AsyncContextImpl.java:269) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest$Servlet3ExecutionContext$Servle3AsychronousResponse.resume(Servlet3AsyncHttpRequest.java:97) [async-http-servlet-3.0-3.0.10.Final.jar:]
at org.hawkular.metrics.api.jaxrs.util.ApiUtils$1.onSuccess(ApiUtils.java:73) [classes:]
at org.hawkular.metrics.api.jaxrs.util.ApiUtils$1.onSuccess(ApiUtils.java:70) [classes:]
at com.google.common.util.concurrent.Futures$4.run(Futures.java:1181) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.Futures$ChainingListenableFuture$1.run(Futures.java:872) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.Futures$ImmediateFuture.addListener(Futures.java:102) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.Futures$ChainingListenableFuture.run(Futures.java:868) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.Futures$ChainingListenableFuture$1.run(Futures.java:872) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.Futures$ImmediateFuture.addListener(Futures.java:102) [guava-16.0.1.jar:]
at com.google.common.util.concurrent.Futures$ChainingListenableFuture.run(Futures.java:868) [guava-16.0.1.jar:]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_20]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_20]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_20]
{noformat}
At this point I cannot rule out the possibility that it is something in our application code, so we will try to reproduce with something simpler. https://issues.jboss.org/browse/WFLY-4352 is mentioned, and I see that it is marked resolved for beta 2. How similar are these issues?
> onComplete for async listeners not always called
> ------------------------------------------------
>
> Key: WFLY-3962
> URL: https://issues.jboss.org/browse/WFLY-3962
> Project: WildFly
> Issue Type: Bug
> Components: Web (Undertow)
> Affects Versions: 8.0.0.Final, 8.1.0.Final
> Reporter: Heiko Rupp
> Assignee: Stuart Douglas
> Fix For: 8.2.0.Final, 9.0.0.Beta1
>
>
> I have a servlet filter that does
> chain.doFilter(requestWrapper, responseWrapper);
> if (request.isAsyncStarted()) {
> asyncListener = request.getAsyncContext().createListener(JsonPAsyncListener.class);
> request.getAsyncContext().addListener(asyncListener, requestWrapper, responseWrapper);
> }
> And (sometimes) this works well so that the onComplete() method of the listener is called.
> But this does not happen always. In some (repeatable) condition none of the callback methods in my AsyncListener are called.
> I was first thinking that the servlet (resteasy) behind chain.doFilter() is so fast that it completes
> before I can add the listener.
> But then I tried adding a Thread.sleep() in the RE code which did not change anything.
> Similar when I do a startAsync() and add the listener before calling chain.doFilter()
> This happens both on Wfly 8.0 and 8.1
> Basically it boils down that if the "backend" uses Futures.immediateFuture(result) , onComplete is not called.
> I have created a as small as possible war file + a read me on how to drive that via curl.
> See https://github.com/pilhuhn/misc/tree/master/web-goo
> I just added 2 examples to the readme file that show that if no
> wrapping by the filter is requested, the resteasy code works with
> both Futures.immediate... and Futures.transform(...)
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months
[JBoss JIRA] (ELY-162) Review HexConverter
by Farah Juma (JIRA)
[ https://issues.jboss.org/browse/ELY-162?page=com.atlassian.jira.plugin.sy... ]
Farah Juma reassigned ELY-162:
------------------------------
Assignee: Farah Juma
> Review HexConverter
> -------------------
>
> Key: ELY-162
> URL: https://issues.jboss.org/browse/ELY-162
> Project: WildFly Elytron
> Issue Type: Enhancement
> Components: API / SPI
> Reporter: Darran Lofthouse
> Assignee: Farah Juma
> Fix For: 1.0.0.Alpha1
>
>
> Firstly this should probably now live under 'org.wildfly.security.util' however should it be better integrated with the existing content here as really it is just an alternative base.
> Additional control that may be desirable is selection of the alphabet, depending on the reason for the conversion specifying the case may be desirable.
> Secondly there may be a desire to control formatting: -
> - Option to prefix each pair with 0x
> - Between each pair use a space as a delimiter.
> - Between each pair use ':' as a delimiter.
> After x number of pairs the option to insert a newline into the String.
> This list is primarily about creating different presentation representations, being able to decode all these formats could be a nice to have but not essential.
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months
[JBoss JIRA] (WFLY-4374) java.lang.IllegalAccessError and other classloader issues
by John Sipher (JIRA)
[ https://issues.jboss.org/browse/WFLY-4374?page=com.atlassian.jira.plugin.... ]
John Sipher updated WFLY-4374:
------------------------------
Description:
Update 4/1/2015: I have verified that 9.0.0.Beta2 fixes the IllegalAccessError and the war file in problem-demo.zip/hello-world6/target now duplicates the original problem. The order of the jar files in the classpath should be
WEB-INF/lib/patch/patch2.jar
WEB-INF/lib/patch/patch1.jar
WEB-INF/lib/base/helloworld-sans-cdi.jar
org.jboss.as.quickstarts.helloworld.HelloService exists in both patch2.jar and helloworld-sans-cdi.jar. The version from patch2.jar should be used because it is first in the classpath, but the classloader is picking up the original class from helloworld-sans-cdi.jar instead.
Original problem description follows:
We use manifest-only jar files in our WAR and EAR files to control the order that jar files are searched for classes. When we issue patches, we put the modified class(es) in a separate jar file, add that jar file to the affected EAR or WAR file, and update the classpath in our manifest-only jar file to put the new patch at the beginning of the class path so that it will be used in place of the original class (which is still in the original jar file).
For example, WEB-INF/lib will contain a single jar file named manifest.jar and sub-folders named 3rdparty, base, patch, and custom. The Class-Path entry in WEB-INF/lib/manifest.jar|META-INF/MANIFEST.MF looks like this:
Class-Path: 3rdparty/manifest.jar patch/manifest.jar base/manifest.jar custom/manifest.jar
When we publish a patch, the patch jar file is added to WEB-INF/lib/patch and to the front of the classpath in WEB-INF/lib/patch/manifest.jar's MANIFEST.MF.
This worked fine for us for years with JBoss 4.2.3.GA, 5.1.0.GA, 7.1.2.Final, and 7.2.0.Final, but it's broken in WildFly 8.2.0.Final.
When I run it in debug I can see where the problem shows up in this section of org.jboss.modules.Module (lines 562 - 573).
final String path = pathOfClass(className);
final Map<String, List<LocalLoader>> paths = getPathsUnchecked();
final List<LocalLoader> loaders = paths.get(path);
if (loaders != null) {
Class<?> clazz;
for (LocalLoader loader : loaders) {
clazz = loader.loadClassLocal(className, resolve);
if (clazz != null) {
return clazz;
}
}
}
The modules in the loaders list at line 565 are
* deployment.service.ear.lib/base/shared.jar:main
* deployment.service.ear.lib/base/deployment.jar:main
* deployment.service.ear.lib/patch/patch.jar:main
The last one should actually be the first in the list. I haven't been able to track down the actual source of the error yet.
I've been trying to create a simple example based on the helloworld quickstart to reproduce the problem, but I haven't been successful yet because of other classloader errors that I've run into. I decided to go ahead and open this issue and document the things I am able to reproduce. Those are:
1. CDI injection doesn't work when the annotated classes are in jar files under WEB-INF/lib instead of unpacked in WEB-INF/classes.
2. WildFly doesn't process the javax.servlet.annotation.WebServlet annotation if the jar file containing the annotated class is in a sub-folder of WEB-INF/lib.
3. WildFly throws a java.lang.IllegalAccessError trying to load a "patched" class.
The first problem exists in both 7.2.0.Final and 8.2.0.Final. The other two problems are new in 8.2.0.Final.
was:
We use manifest-only jar files in our WAR and EAR files to control the order that jar files are searched for classes. When we issue patches, we put the modified class(es) in a separate jar file, add that jar file to the affected EAR or WAR file, and update the classpath in our manifest-only jar file to put the new patch at the beginning of the class path so that it will be used in place of the original class (which is still in the original jar file).
For example, WEB-INF/lib will contain a single jar file named manifest.jar and sub-folders named 3rdparty, base, patch, and custom. The Class-Path entry in WEB-INF/lib/manifest.jar|META-INF/MANIFEST.MF looks like this:
Class-Path: 3rdparty/manifest.jar patch/manifest.jar base/manifest.jar custom/manifest.jar
When we publish a patch, the patch jar file is added to WEB-INF/lib/patch and to the front of the classpath in WEB-INF/lib/patch/manifest.jar's MANIFEST.MF.
This worked fine for us for years with JBoss 4.2.3.GA, 5.1.0.GA, 7.1.2.Final, and 7.2.0.Final, but it's broken in WildFly 8.2.0.Final.
When I run it in debug I can see where the problem shows up in this section of org.jboss.modules.Module (lines 562 - 573).
final String path = pathOfClass(className);
final Map<String, List<LocalLoader>> paths = getPathsUnchecked();
final List<LocalLoader> loaders = paths.get(path);
if (loaders != null) {
Class<?> clazz;
for (LocalLoader loader : loaders) {
clazz = loader.loadClassLocal(className, resolve);
if (clazz != null) {
return clazz;
}
}
}
The modules in the loaders list at line 565 are
* deployment.service.ear.lib/base/shared.jar:main
* deployment.service.ear.lib/base/deployment.jar:main
* deployment.service.ear.lib/patch/patch.jar:main
The last one should actually be the first in the list. I haven't been able to track down the actual source of the error yet.
I've been trying to create a simple example based on the helloworld quickstart to reproduce the problem, but I haven't been successful yet because of other classloader errors that I've run into. I decided to go ahead and open this issue and document the things I am able to reproduce. Those are:
1. CDI injection doesn't work when the annotated classes are in jar files under WEB-INF/lib instead of unpacked in WEB-INF/classes.
2. WildFly doesn't process the javax.servlet.annotation.WebServlet annotation if the jar file containing the annotated class is in a sub-folder of WEB-INF/lib.
3. WildFly throws a java.lang.IllegalAccessError trying to load a "patched" class.
The first problem exists in both 7.2.0.Final and 8.2.0.Final. The other two problems are new in 8.2.0.Final.
Affects Version/s: 9.0.0.Beta2
> java.lang.IllegalAccessError and other classloader issues
> ---------------------------------------------------------
>
> Key: WFLY-4374
> URL: https://issues.jboss.org/browse/WFLY-4374
> Project: WildFly
> Issue Type: Bug
> Components: Class Loading
> Affects Versions: 8.2.0.Final, 9.0.0.Beta2
> Environment: Windows 7/Java 7 update 67
> Reporter: John Sipher
> Assignee: David Lloyd
> Attachments: problem-demo.zip
>
>
> Update 4/1/2015: I have verified that 9.0.0.Beta2 fixes the IllegalAccessError and the war file in problem-demo.zip/hello-world6/target now duplicates the original problem. The order of the jar files in the classpath should be
> WEB-INF/lib/patch/patch2.jar
> WEB-INF/lib/patch/patch1.jar
> WEB-INF/lib/base/helloworld-sans-cdi.jar
> org.jboss.as.quickstarts.helloworld.HelloService exists in both patch2.jar and helloworld-sans-cdi.jar. The version from patch2.jar should be used because it is first in the classpath, but the classloader is picking up the original class from helloworld-sans-cdi.jar instead.
> Original problem description follows:
> We use manifest-only jar files in our WAR and EAR files to control the order that jar files are searched for classes. When we issue patches, we put the modified class(es) in a separate jar file, add that jar file to the affected EAR or WAR file, and update the classpath in our manifest-only jar file to put the new patch at the beginning of the class path so that it will be used in place of the original class (which is still in the original jar file).
>
> For example, WEB-INF/lib will contain a single jar file named manifest.jar and sub-folders named 3rdparty, base, patch, and custom. The Class-Path entry in WEB-INF/lib/manifest.jar|META-INF/MANIFEST.MF looks like this:
> Class-Path: 3rdparty/manifest.jar patch/manifest.jar base/manifest.jar custom/manifest.jar
>
> When we publish a patch, the patch jar file is added to WEB-INF/lib/patch and to the front of the classpath in WEB-INF/lib/patch/manifest.jar's MANIFEST.MF.
>
> This worked fine for us for years with JBoss 4.2.3.GA, 5.1.0.GA, 7.1.2.Final, and 7.2.0.Final, but it's broken in WildFly 8.2.0.Final.
> When I run it in debug I can see where the problem shows up in this section of org.jboss.modules.Module (lines 562 - 573).
> final String path = pathOfClass(className);
> final Map<String, List<LocalLoader>> paths = getPathsUnchecked();
> final List<LocalLoader> loaders = paths.get(path);
> if (loaders != null) {
> Class<?> clazz;
> for (LocalLoader loader : loaders) {
> clazz = loader.loadClassLocal(className, resolve);
> if (clazz != null) {
> return clazz;
> }
> }
> }
> The modules in the loaders list at line 565 are
> * deployment.service.ear.lib/base/shared.jar:main
> * deployment.service.ear.lib/base/deployment.jar:main
> * deployment.service.ear.lib/patch/patch.jar:main
> The last one should actually be the first in the list. I haven't been able to track down the actual source of the error yet.
> I've been trying to create a simple example based on the helloworld quickstart to reproduce the problem, but I haven't been successful yet because of other classloader errors that I've run into. I decided to go ahead and open this issue and document the things I am able to reproduce. Those are:
> 1. CDI injection doesn't work when the annotated classes are in jar files under WEB-INF/lib instead of unpacked in WEB-INF/classes.
> 2. WildFly doesn't process the javax.servlet.annotation.WebServlet annotation if the jar file containing the annotated class is in a sub-folder of WEB-INF/lib.
> 3. WildFly throws a java.lang.IllegalAccessError trying to load a "patched" class.
> The first problem exists in both 7.2.0.Final and 8.2.0.Final. The other two problems are new in 8.2.0.Final.
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months
[JBoss JIRA] (WFCORE-368) Ability for processes to be placed in a state rejecting config changes and requiring a restart
by Brian Stansberry (JIRA)
[ https://issues.jboss.org/browse/WFCORE-368?page=com.atlassian.jira.plugin... ]
Brian Stansberry updated WFCORE-368:
------------------------------------
Fix Version/s: (was: 1.0.0.CR1)
> Ability for processes to be placed in a state rejecting config changes and requiring a restart
> ----------------------------------------------------------------------------------------------
>
> Key: WFCORE-368
> URL: https://issues.jboss.org/browse/WFCORE-368
> Project: WildFly Core
> Issue Type: Enhancement
> Components: Domain Management
> Reporter: Brian Stansberry
> Assignee: Brian Stansberry
>
> If a condition occurs whereby a managed process is in an unknown and inconsistent state, we need the ability to mark the process as being unsafe to modify in terms of configuration and requiring restart.
> Examples of this kind of situation in a standalone server would include:
> 1) timeouts waiting for MSC stability as envisioned in WFLY-2741.
> 2) failures that occur in operation rollback.
> In these cases, it is no longer practical to determine how internal service state relates to configuration state. Allowing further configuration changes will exacerbate the situation. The process should be restarted in order to restore consistency before allowing further config changes.
> In a domain environment this can also include servers that are inconsistent with respect to the domain model because some update has failed on that server but the rollout plan allowed the update to commit on other servers.
> In this case, the server config is inconsistent with the domain and subsequent changes to the domain will not make it consistent, so they should not be propagated to the server. The server needs to be restarted in order to get a complete configuration.
--
This message was sent by Atlassian JIRA
(v6.3.11#6341)
9 years, 9 months