<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
In this case, I want to apologize for my previously incorrect
statement. <br>
<br>
Thomas, we can work together to have this all set up in 1.1.2.Final
which is due next week, what do you think ?<br>
<br>
Best Regards,<br>
<br>
George Gastaldi<br>
<br>
On 11/05/2012 02:42 PM, Lincoln Baxter, III wrote:
<blockquote
cite="mid:CAEp_U4Eiw-6ZTJfJyb6GQ80PDy=CZwhuXXK1Q7S9YFmgo8WXXQ@mail.gmail.com"
type="cite">Yes, just for clarification, we are still making major
updates and improvements to 1.x in parallel to 2.0 research.<br>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">On Mon, Nov 5, 2012 at 3:54 AM, Paul
Bakker <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:paul.bakker.nl@gmail.com" target="_blank">paul.bakker.nl@gmail.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="auto">
<div>+1 for any non-breaking changes. 2.0 is still far
away and development on 1.0 shouldn't stop until then. </div>
<div><br>
Sent from my iPhone</div>
<div>
<div class="h5">
<div><br>
On 5 nov. 2012, at 01:27, "Lincoln Baxter, III" <<a
moz-do-not-send="true"
href="mailto:lincolnbaxter@gmail.com"
target="_blank">lincolnbaxter@gmail.com</a>>
wrote:<br>
<br>
</div>
<blockquote type="cite">
<div>I think performance improvements in Forge 1.x
are very important even now!<br>
<br>
It's going to be around for a very long time and
while we are working on Forge 2.0 now, the kinds
of improvements you are talking about, Thomas, are
very significant!<br>
<br>
How can we help? Do you think you could put this
code into a branch with a single commit (or just
one for each change) so that we can see just how
much you had to change?<br>
<br>
The problem with the weld container is the
Hibernate Tools plugin. If that one works, and the
Openshift and AS7 plugins work, then it's safe to
assume that it's working fine. It was a hack to
solve a classloading problem, but if we can fix it
now, that's great!<br>
<br>
~Lincoln<br>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">On Sat, Nov 3, 2012 at
3:27 PM, George Gastaldi <span dir="ltr"><<a
moz-do-not-send="true"
href="mailto:ggastald@redhat.com"
target="_blank">ggastald@redhat.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote"
style="margin:0 0 0 .8ex;border-left:1px
#ccc solid;padding-left:1ex">Hi Thomas,<br>
<br>
Nice to know that you've found some
improvements for Forge 1.x startup time.
However, we are rewriting Forge in 2.x from
the ground up and we're focusing on
performance and flexibility in first place.<br>
<br>
We encourage you to try the 2.0 branch and
help us on finding some possible performance
problems if you feel so.<br>
<br>
As for now, we are avoiding any major
changes and updates to 1.x.<br>
<br>
Best Regards,<br>
<br>
George Gastaldi<br>
<br>
Em 03/11/2012, às 15:41, Thomas Frühbeck
<<a moz-do-not-send="true"
href="mailto:fruehbeck@aon.at"
target="_blank">fruehbeck@aon.at</a>>
escreveu:<br>
<div>
<div><br>
> Hi,<br>
><br>
> following the discussions about
boot-up performance of Forge I made some<br>
> investigations using a profiler.<br>
> After testing a lot of different
scenarios I would like to share my<br>
> results and ask for your opinion on
it.<br>
><br>
>
*************************************************************************************<br>
> Issue 1.: hot spot inv.<br>
>
org.jboss.forge.bus.cdi.ObserverCaptureExtension.scan<br>
> profiling shows that 37% CPU
time are used in firing<br>
> ProcessAnnotatedType events, which
are AFAICS only used to filter old<br>
> event types<br>
> "37,2% - 13.442 ms - 1.866 inv.<br>
>
org.jboss.weld.bootstrap.events.ProcessAnnotatedTypeImpl.fire"<br>
><br>
> By introducing a preparatory
check in ObserverCaptureExtension like<br>
>> if
(isMethodsAnnotated(originalType,
Observes.class)) {<br>
>> ....<br>
>> }<br>
><br>
> and something like:<br>
>> private boolean
isMethodsAnnotated(AnnotatedType<?>
type, Class<?<br>
> extends Annotation> annotation)
{<br>
>> if
(type.getClass().isAnnotationPresent(annotation))<br>
>> return true;<br>
>> for (Method m :
type.getClass().getMethods()) {<br>
>> if
(m.isAnnotationPresent(annotation))<br>
>> return true;<br>
>> for (Annotation[] arr
: m.getParameterAnnotations()) {<br>
>> for (Annotation a :
arr) {<br>
>> if
(a.equals(annotation))<br>
>> return
true;<br>
>> }<br>
>> }<br>
>> }<br>
>> return false;<br>
>> }<br>
><br>
> we could reduce startup by 20%<br>
> "13,8% - 2.438 ms - 1.798 inv.<br>
>
org.jboss.weld.bootstrap.events.ProcessAnnotatedTypeImpl.fire<br>
><br>
> Test: call Forge with commands
"list-plugins" and "exit", like ~>
time<br>
> ((echo forge list-plugins; echo
exit;)| bin/forge)<br>
><br>
> Before optimization:<br>
> ~/forge> time ((echo forge
list-plugins && echo exit)|
bin/forge )<br>
> _____<br>
> | ___|__ _ __ __ _ ___<br>
> | |_ / _ \| `__/ _` |/ _ \ \\<br>
> | _| (_) | | | (_| | __/ //<br>
> |_| \___/|_| \__, |\___|<br>
> |___/<br>
><br>
> [no project]
forge-distribution-1.1.1-SNAPSHOT $
forge list-plugins<br>
>
org.richfaces.forge.richfaces-forge-plugin:1.0.5.Final:1.0.0-SNAPSHOT-b1a6ebed-462f-40e1-ac08-82f927489301<br>
>
com.ocpsoft.forge.prettyfaces-plugin:1.0.2.Final:1.0.0-SNAPSHOT-c6b071ad-a6df-4112-8fff-82ecccd003fb<br>
>
org.jboss.hibernate.forge.hibernate-tools-plugin:1.0.5.Final:1.0.0-SNAPSHOT-afb1da29-a99f-4dd7-b020-5f3ba6073cde<br>
>
org.arquillian.forge.arquillian-plugin:1.0.3-SNAPSHOT:1.0.0-SNAPSHOT-42907982-d02e-4a1d-8ea5-8e66c8013fde<br>
> [no project]
forge-distribution-1.1.1-SNAPSHOT $ exit<br>
><br>
><br>
> real 0m9.721s<br>
> user 0m26.533s<br>
> sys 0m0.433s<br>
><br>
> After optimization:<br>
> ~forge1.1.1-weld1.2> time ((echo
forge list-plugins; echo exit;)|
bin/forge)<br>
> Using Forge at
/raid/home/thomas/java/forge1.1.1-weld1.2<br>
> _____<br>
> | ___|__ _ __ __ _ ___<br>
> | |_ / _ \| `__/ _` |/ _ \ \\<br>
> | _| (_) | | | (_| | __/ //<br>
> |_| \___/|_| \__, |\___|<br>
> |___/<br>
><br>
> [no project] forge1.1.1-weld1.2 $
forge list-plugins<br>
>
org.richfaces.forge.richfaces-forge-plugin:1.0.5.Final:1.0.0-SNAPSHOT-b1a6ebed-462f-40e1-ac08-82f927489301<br>
>
com.ocpsoft.forge.prettyfaces-plugin:1.0.2.Final:1.0.0-SNAPSHOT-c6b071ad-a6df-4112-8fff-82ecccd003fb<br>
>
org.jboss.hibernate.forge.hibernate-tools-plugin:1.0.5.Final:1.0.0-SNAPSHOT-afb1da29-a99f-4dd7-b020-5f3ba6073cde<br>
>
org.arquillian.forge.arquillian-plugin:1.0.3-SNAPSHOT:1.0.0-SNAPSHOT-42907982-d02e-4a1d-8ea5-8e66c8013fde<br>
> [no project] forge1.1.1-weld1.2 $
exit<br>
><br>
><br>
> real 0m6.016s<br>
> user 0m14.482s<br>
> sys 0m0.449s<br>
><br>
><br>
>
*************************************************************************************<br>
> Issue 2.: double starting of Weld
container<br>
> I admit that I do not fully
understand, what I did and if this
really<br>
> provides the full solution, but it
worked and produced a fully<br>
> functional Forge instance.<br>
><br>
> I tried to restructure the
Bootstrap logic a bit:<br>
><br>
>
initializeClassloader();<br>
> WeldContainer
container = weld.initialize();<br>
> manager =
container.getBeanManager();<br>
><br>
> try<br>
> {<br>
> loadPlugins();<br>
>
weld.reInitialize();<br>
><br>
> where initializeClassloader already
uses the CompositeClassloader:<br>
><br>
> private static void
initializeClassloader() {<br>
> ModuleLoader moduleLoader =
Module.getBootModuleLoader();<br>
><br>
> CompositeClassLoader
composite = new CompositeClassLoader();<br>
>
composite.add(Module.forClassLoader(Bootstrap.class.getClassLoader(),<br>
> true).getClassLoader());<br>
><br>
>
Thread.currentThread().setContextClassLoader(composite);<br>
> }<br>
><br>
> and loadPlugins simply adds more
classloaders:<br>
><br>
> CompositeClassLoader
composite =<br>
>
(CompositeClassLoader)Thread.currentThread().getContextClassLoader();<br>
> for (PluginEntry plugin :
toLoad)<br>
> {<br>
> Module module =<br>
>
moduleLoader.loadModule(ModuleIdentifier.fromString(plugin.toModuleId()));<br>
>
composite.add(module.getClassLoader());<br>
><br>
><br>
> This way the classes are already
available in the correct classloader<br>
> for the later
ModularWeld.reInitialize():<br>
><br>
> public void reInitialize() {<br>
> bootstrap.revisit();<br>
> bootstrap.validateBeans();<br>
>
bootstrap.endInitialization();<br>
> }<br>
><br>
> Where Bootstrap.revisit simply
revisits the BeanDeployments which have<br>
> been newly found:<br>
><br>
> private static class
DeploymentVisitor {<br>
> .....<br>
> public
Map<BeanDeploymentArchive,
BeanDeployment> revisit() {<br>
> for
(BeanDeploymentArchive archvive :<br>
>
deployment.getBeanDeploymentArchives())
{<br>
> if<br>
>
(!managerAwareBeanDeploymentArchives.containsKey(archvive))
{<br>
> visit(archvive,
managerAwareBeanDeploymentArchives,<br>
> new
HashSet<BeanDeploymentArchive>(),
true);<br>
> BeanDeployment
bd =<br>
>
managerAwareBeanDeploymentArchives.get(archvive);<br>
>
bd.createBeans(environment);<br>
>
bd.deployBeans(environment);<br>
> }<br>
> }<br>
> return
managerAwareBeanDeploymentArchives;<br>
> }<br>
><br>
><br>
>
*************************************************************************************<br>
> Issue 3.: invocation of potentially
expensive operations on<br>
> non-annotated or
annotation-relevant classes<br>
> The current BeanDeployer simply
invokes ProcessAnnotatedType on any<br>
> class, w/o checking, if this class
is used by any annotation anywhere.<br>
> By jandexing all jars and
assembling the dispersed Jandex indices
during<br>
> URLScanning we could reduce the
expensive WeldClass conversion.<br>
><br>
> Original:<br>
> 11.108 ms - 2.024 inv.
org.jboss.weld.bootstrap.BeanDeployer.addClass<br>
> Jandex-aware:<br>
> 4.721 ms - 990 inv.
org.jboss.weld.bootstrap.BeanDeployer.addClass<br>
><br>
> Possible solution:<br>
> - 1. URLHandler scans Jandex
file locations<br>
><br>
> protected void
addToDiscovered(String name, URL url) {<br>
> ...<br>
> } else if
(name.endsWith(JANDEX_IDX)) {<br>
>
discoveredJandexIndexUrls.add(url);<br>
> }<br>
> }<br>
><br>
> - 2. URLScanner assembles all
found Jandex indices:<br>
><br>
> List<Index>
jandexIndexes = new
ArrayList<Index>();<br>
> for (URL jandexUrl :
handler.getDiscoveredJandexIndexUrls())
{<br>
>
jandexIndexes.add(new<br>
>
IndexReader(jandexUrl.openStream()).read());<br>
> }<br>
><br>
> - 3. BeanDeployer does
expensive WeldClass loading only if
class is<br>
> mentioned in the Jandex indices<br>
> - 3.a. first collapse the
Jandex-indices to a simple list of class<br>
> names:<br>
> for (Index jandexIndex :
jandexIndexes) {<br>
> for
(List<AnnotationInstance> aiList :<br>
>
jandexIndex.getAnnotations().values()) {<br>
> for
(AnnotationInstance ai : aiList) {<br>
>
AnnotationTarget at = ai.target();<br>
> if (at
instanceof ClassInfo) {<br>
>
jandexAnnotated.add(((ClassInfo)at).name().toString());<br>
> } else if (at
instanceof MethodInfo) {<br>
>
jandexAnnotated.add(((MethodInfo)at).declaringClass().name().toString());<br>
> } else if (at
instanceof MethodParameterInfo) {<br>
>
jandexAnnotated.add(((MethodParameterInfo)at).method().declaringClass().name().toString());<br>
> } else if (at
instanceof FieldInfo) {<br>
>
jandexAnnotated.add(((FieldInfo)at).declaringClass().name().toString());<br>
> }<br>
> }<br>
> }<br>
> }<br>
><br>
> - 3.b. query the aggregated
list of Jandex-aware classes<br>
><br>
> public BeanDeployer
addClass(String className) {<br>
> Class<?> clazz =
loadClass(className);<br>
> if (clazz != null
&& isBeanCandidate(clazz)
&&<br>
> jandexContains(className)) {<br>
> WeldClass<?>
weldClass = loadWeldClass(clazz);<br>
><br>
><br>
> Yet unsolved issue is the question,
wheter an index is found in the<br>
> corresponding Archive or not, so
not to enforce Jandexing _all_ jars for<br>
> Forge.<br>
> Jandexing is very easy though:
jandex -m <jar><br>
><br>
> The abovementioned solutions have
been implemented and produced a<br>
> functional and correctly working
Forge instance.<br>
> AFAICS the solution for issue 2
could be a means to solve the reloading<br>
> of plugins too, but I didn't
implement and verify this.<br>
><br>
> The sources are not available
online, because the current
implementation<br>
> is highly fragile and not safe for
simple usage - too many changes in<br>
> APIs, dependencies, etc.<br>
><br>
> Comments welcome!<br>
><br>
> Regards,<br>
> Thomas<br>
><br>
>
_______________________________________________<br>
> forge-dev mailing list<br>
> <a moz-do-not-send="true"
href="mailto:forge-dev@lists.jboss.org"
target="_blank">forge-dev@lists.jboss.org</a><br>
> <a moz-do-not-send="true"
href="https://lists.jboss.org/mailman/listinfo/forge-dev"
target="_blank">https://lists.jboss.org/mailman/listinfo/forge-dev</a><br>
<br>
_______________________________________________<br>
forge-dev mailing list<br>
<a moz-do-not-send="true"
href="mailto:forge-dev@lists.jboss.org"
target="_blank">forge-dev@lists.jboss.org</a><br>
<a moz-do-not-send="true"
href="https://lists.jboss.org/mailman/listinfo/forge-dev"
target="_blank">https://lists.jboss.org/mailman/listinfo/forge-dev</a><br>
</div>
</div>
</blockquote>
</div>
<br>
<br clear="all">
<br>
-- <br>
Lincoln Baxter, III<br>
<a moz-do-not-send="true"
href="http://ocpsoft.org" target="_blank">http://ocpsoft.org</a><br>
"Simpler is better."<br>
</div>
</div>
</blockquote>
<blockquote type="cite">
<div><span>_______________________________________________</span><br>
<span>forge-dev mailing list</span><br>
<span><a moz-do-not-send="true"
href="mailto:forge-dev@lists.jboss.org"
target="_blank">forge-dev@lists.jboss.org</a></span><br>
<span><a moz-do-not-send="true"
href="https://lists.jboss.org/mailman/listinfo/forge-dev"
target="_blank">https://lists.jboss.org/mailman/listinfo/forge-dev</a></span><br>
</div>
</blockquote>
</div>
</div>
</div>
<br>
_______________________________________________<br>
forge-dev mailing list<br>
<a moz-do-not-send="true"
href="mailto:forge-dev@lists.jboss.org">forge-dev@lists.jboss.org</a><br>
<a moz-do-not-send="true"
href="https://lists.jboss.org/mailman/listinfo/forge-dev"
target="_blank">https://lists.jboss.org/mailman/listinfo/forge-dev</a><br>
<br>
</blockquote>
</div>
<br>
<br clear="all">
<br>
-- <br>
Lincoln Baxter, III<br>
<a moz-do-not-send="true" href="http://ocpsoft.org"
target="_blank">http://ocpsoft.org</a><br>
"Simpler is better."<br>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
forge-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:forge-dev@lists.jboss.org">forge-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/forge-dev">https://lists.jboss.org/mailman/listinfo/forge-dev</a>
</pre>
</blockquote>
<br>
<div class="moz-signature">-- <br>
<b>George Gastaldi</b> | <i>Senior Software Engineer</i> <br>
JBoss Forge Team<br>
Red Hat<br>
</div>
</body>
</html>