<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dariusz Ludera Homepage</title>
	<atom:link href="http://ludera.info/feed" rel="self" type="application/rss+xml" />
	<link>http://ludera.info</link>
	<description>Dariusz Ludera oficjalna strona. Programista Java i JEE. Dariusz Ludera Homepage. Java and JEE developer.</description>
	<lastBuildDate>Sun, 06 Jun 2010 19:05:52 +0000</lastBuildDate>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Monitoring podstawowych parametrów JVM z poziomu web aplikacji</title>
		<link>http://ludera.info/java/monitoring-podstawowych-parametrow-jvm-z-poziomu-web-aplikacji</link>
		<comments>http://ludera.info/java/monitoring-podstawowych-parametrow-jvm-z-poziomu-web-aplikacji#comments</comments>
		<pubDate>Sun, 06 Jun 2010 19:05:52 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[richfaces]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=552</guid>
		<description><![CDATA[Problem Monitoring podstawowych parametrów JVM z poziomu web aplikacji &#8211; przydatne zwłaszcza wtedy, gdy nasz serwer aplikacji/kontener serwletów nie pokazuje takich informacji w swojej webowej konsoli i nie mamy możliwości szybkiego podpięcia się VisualVM albo JConsole (brak aktywowanego jmxremote, firewalle, czy cokolwiek innego uniemożliwiającego połączenie), a podejrzewamy że coś niedobrego może dziać się z naszą [...]]]></description>
			<content:encoded><![CDATA[<h2>Problem</h2>
<p>Monitoring podstawowych parametrów JVM z poziomu web aplikacji &#8211; przydatne zwłaszcza wtedy, gdy nasz serwer aplikacji/kontener serwletów nie pokazuje takich informacji w swojej webowej konsoli i nie mamy możliwości szybkiego podpięcia się <a title="VisualVM" href="https://visualvm.dev.java.net/" onclick="pageTracker._trackPageview('/outgoing/visualvm.dev.java.net/?referer=');">VisualVM</a> albo <a href="http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html" onclick="pageTracker._trackPageview('/outgoing/java.sun.com/developer/technicalArticles/J2SE/jconsole.html?referer=');">JConsole</a> (brak aktywowanego jmxremote, firewalle, czy cokolwiek innego uniemożliwiającego połączenie), a podejrzewamy że coś niedobrego może dziać się z naszą aplikacją.</p>
<h2>Rozwiązanie</h2>
<p>Wrzucenie prostej stronki JSP, która nam takie parametry wyświetli.</p>
<p>Poniżej listing (po moich drobnych modyfikacjach) zapożyczony z <a href="http://www.freshblurbs.com/explaining-java-lang-outofmemoryerror-permgen-space" onclick="pageTracker._trackPageview('/outgoing/www.freshblurbs.com/explaining-java-lang-outofmemoryerror-permgen-space?referer=');">http://www.freshblurbs.com/explaining-java-lang-outofmemoryerror-permgen-space</a></p>
<p>Skryptlet (tak wiem, śmierdzi) użyty na tej stronie pozwala wrzucać ją do aplikacji bez potrzeby restartu serwera/redeploy aplikacji.</p>
<pre class="brush: java;">
&lt;%@page contentType=&quot;text/html&quot; pageEncoding=&quot;UTF-8&quot;%&gt;
&lt;%@ page import=&quot;java.util.*, java.lang.management.*&quot; %&gt;
&lt;%@ taglib uri=&quot;http://java.sun.com/jstl/core_rt&quot; prefix=&quot;c&quot; %&gt;
&lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; prefix=&quot;fmt&quot; %&gt;
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
    	               &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;

&lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
    &lt;title&gt;JVM Memory Monitor&lt;/title&gt;
    &lt;style type=&quot;text/css&quot;&gt;
      td {
        text-align: right;
      }
    &lt;/style&gt;
  &lt;/head&gt;
&lt;body&gt;
  &lt;jsp:scriptlet&gt;
    MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    pageContext.setAttribute(&quot;memoryBean&quot;, memoryBean, PageContext.PAGE_SCOPE);

    List poolBeans = ManagementFactory.getMemoryPoolMXBeans();
    pageContext.setAttribute(&quot;poolBeans&quot;, poolBeans, PageContext.PAGE_SCOPE);
  &lt;/jsp:scriptlet&gt;

  &lt;h3&gt;Total Memory&lt;/h3&gt;
  &lt;table border=&quot;1&quot; width=&quot;100%&quot;&gt;
    &lt;tr&gt;
      &lt;th&gt;usage&lt;/th&gt;
      &lt;th&gt;init&lt;/th&gt;
      &lt;th&gt;used&lt;/th&gt;
      &lt;th&gt;committed&lt;/th&gt;
      &lt;th&gt;max&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Heap Memory Usage&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.heapMemoryUsage.init / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.heapMemoryUsage.used / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.heapMemoryUsage.committed / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.heapMemoryUsage.max / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Non-heap Memory Usage&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.nonHeapMemoryUsage.init / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.nonHeapMemoryUsage.used / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.nonHeapMemoryUsage.committed / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;td&gt;&lt;fmt:formatNumber value=&quot;${pageScope.memoryBean.nonHeapMemoryUsage.max / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;

  &lt;h3&gt;Memory Pools&lt;/h3&gt;
  &lt;table border=&quot;1&quot; width=&quot;100%&quot;&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Usage&lt;/th&gt;
      &lt;th&gt;Init&lt;/th&gt;
      &lt;th&gt;Used&lt;/th&gt;
      &lt;th&gt;Committed&lt;/th&gt;
      &lt;th&gt;Max&lt;/th&gt;
    &lt;/tr&gt;
    &lt;c:forEach var=&quot;bean&quot; items=&quot;${pageScope.poolBeans}&quot;&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;c:out value=&quot;${bean.name}&quot; /&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;Memory Usage&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.usage.init / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.usage.used / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.usage.committed / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.usage.max / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;Peak Usage&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.peakUsage.init / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.peakUsage.used / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.peakUsage.committed / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
        &lt;td&gt;&lt;fmt:formatNumber value=&quot;${bean.peakUsage.max / (1024 * 1024)}&quot; maxFractionDigits=&quot;1&quot;/&gt; MB&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/c:forEach&gt;
  &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Efekt poniżej:</p>
<p><a href="http://ludera.info/wp-content/uploads/2010/06/jvmMemoryMonitorWithJstl1.png"><img class="aligncenter size-full wp-image-561" title="jvmMemoryMonitorWithJstl" src="http://ludera.info/wp-content/uploads/2010/06/jvmMemoryMonitorWithJstl1.png" alt="" width="396" height="391" /></a></p>
<p>To rozwiązanie tak mi się spodobało, że z rozpędu napisałem sobie to samo w Richfaces. Strona odświeża się automatycznie co zadany przedział czasu (w ms). Wykorzystanie Ajax Push/Poll nie powala na pewno z punktu widzenia wydajności, jest natomiast rozwiązaniem banalnym do zaimplementowania:</p>
<pre class="brush: java;">
&lt;html xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
    xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
    xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
    xmlns:a4j=&quot;http://richfaces.org/a4j&quot;
    xmlns:rich=&quot;http://richfaces.org/rich&quot;&gt;

&lt;head&gt;
    &lt;title&gt;JVM Memory Monitor&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;a4j:region&gt;
        &lt;h:form&gt;
            &lt;a4j:poll id=&quot;poll&quot; interval=&quot;#{jvmPerformanceManager.interval}&quot; enabled=&quot;#{jvmPerformanceManager.pollEnabled}&quot; reRender=&quot;polledPanel, poll&quot;/&gt;
        &lt;/h:form&gt;
    &lt;/a4j:region&gt;
    &lt;h:form prependId=&quot;false&quot;&gt;
        &lt;h:panelGrid id=&quot;polledPanel&quot; columns=&quot;1&quot;&gt;
            &lt;h3&gt;Total Memory&lt;/h3&gt;
            &lt;rich:dataTable value=&quot;2&quot; style=&quot;text-align: right&quot;&gt;
                &lt;f:facet name=&quot;header&quot;&gt;
                    &lt;rich:columnGroup&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Name&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Init&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Used&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Committed&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Max&quot; /&gt;
                        &lt;/rich:column&gt;
                    &lt;/rich:columnGroup&gt;
                &lt;/f:facet&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;Heap Memory Usage&quot; /&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.heapMemoryUsage.init / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.heapMemoryUsage.used / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.heapMemoryUsage.committed / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.heapMemoryUsage.max / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column breakBefore=&quot;true&quot;&gt;
                    &lt;h:outputText value=&quot;Non-heap Memory Usage&quot; /&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.nonHeapMemoryUsage.init / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.nonHeapMemoryUsage.used / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.nonHeapMemoryUsage.committed / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{jvmPerformanceManager.memoryBean.nonHeapMemoryUsage.max / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;

                &lt;f:facet name=&quot;footer&quot;&gt;
                    &lt;rich:columnGroup&gt;
                        &lt;rich:column&gt;Last actualization date&lt;/rich:column&gt;
                        &lt;rich:column colspan=&quot;4&quot;&gt;
                            &lt;h:outputText value=&quot;#{jvmPerformanceManager.lastActualization}&quot;&gt;
                                &lt;f:convertDateTime pattern=&quot;yyyy-MM-dd HH:mm:ss&quot; timeZone=&quot;#{jvmPerformanceManager.timeZone}&quot;/&gt;
                            &lt;/h:outputText&gt;
                        &lt;/rich:column&gt;
                    &lt;/rich:columnGroup&gt;
                &lt;/f:facet&gt;
            &lt;/rich:dataTable&gt;

            &lt;h3&gt;Memory Pools&lt;/h3&gt;
            &lt;rich:dataTable var=&quot;poolBean&quot; value=&quot;#{jvmPerformanceManager.poolList}&quot;
                style=&quot;text-align: right&quot;&gt;
                &lt;f:facet name=&quot;header&quot;&gt;
                    &lt;rich:columnGroup&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Name&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Usage&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Init&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Used&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Committed&quot; /&gt;
                        &lt;/rich:column&gt;
                        &lt;rich:column&gt;
                            &lt;h:outputText value=&quot;Max&quot; /&gt;
                        &lt;/rich:column&gt;
                    &lt;/rich:columnGroup&gt;
                &lt;/f:facet&gt;
                &lt;rich:column rowspan=&quot;2&quot;&gt;
                    &lt;h:outputText value=&quot;#{poolBean.name}&quot; /&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;Memory&quot; /&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.usage.init / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.usage.used / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.usage.committed / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.usage.max / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column breakBefore=&quot;true&quot;&gt;
                    &lt;h:outputText value=&quot;Peak&quot; /&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.peakUsage.init / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.peakUsage.used / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText
                        value=&quot;#{poolBean.peakUsage.committed / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
                &lt;rich:column&gt;
                    &lt;h:outputText value=&quot;#{poolBean.peakUsage.max / (1024 * 1024)}&quot;&gt;
                        &lt;f:convertNumber pattern=&quot;#,##0.0 MB&quot; locale=&quot;US&quot; /&gt;
                    &lt;/h:outputText&gt;
                &lt;/rich:column&gt;
            &lt;/rich:dataTable&gt;

            &lt;h:panelGrid columns=&quot;2&quot;&gt;
                &lt;h:column&gt;
                    &lt;a4j:commandButton id=&quot;controlBtn&quot;
                        value=&quot;#{jvmPerformanceManager.pollEnabled?'Stop':'Start'}&quot; reRender=&quot;polledPanel, poll&quot;&gt;
                    &lt;a4j:actionparam name=&quot;polling&quot; value=&quot;#{!jvmPerformanceManager.pollEnabled}&quot;
                        assignTo=&quot;#{jvmPerformanceManager.pollEnabled}&quot; /&gt;
                    &lt;/a4j:commandButton&gt;
                &lt;/h:column&gt;
                &lt;h:column&gt;
                    &lt;a4j:outputPanel style=&quot;display: inline&quot; rendered=&quot;#{!jvmPerformanceManager.pollEnabled}&quot;&gt;
                        &lt;h:outputText value=&quot; with &quot; /&gt;
                        &lt;h:inputText value=&quot;#{jvmPerformanceManager.interval}&quot;&gt;
                            &lt;f:validateLongRange minimum=&quot;500&quot; /&gt;
                        &lt;/h:inputText&gt;
                        &lt;h:outputText value=&quot; ms interval.&quot; /&gt;
                    &lt;/a4j:outputPanel&gt;
                &lt;/h:column&gt;
            &lt;/h:panelGrid&gt;
        &lt;/h:panelGrid&gt;
    &lt;/h:form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<pre class="brush: java;">
package info.ludera.helper;

import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;

@ManagedBean(name=&quot;jvmPerformanceManager&quot;)
@SessionScoped
public class JvmPerformanceManager implements Serializable {

    private MemoryMXBean memoryBean;

    private List&lt;MemoryPoolMXBean&gt; poolList;

    private Boolean pollEnabled = true;

    /**
     * Interval in milliseconds. Default 10s.
     */
    private Long interval = 10*1000l;

    private String timeZone;

    public JvmPerformanceManager() {
        getActualMemoryInfo(null);
        timeZone = readDefaultHostTimeZone();
    }

    private String readDefaultHostTimeZone() {
        return TimeZone.getDefault().getID();
    }

    public void getActualMemoryInfo(ActionEvent actionEvent) {
        memoryBean = ManagementFactory.getMemoryMXBean();
        poolList = ManagementFactory.getMemoryPoolMXBeans();
    }

    public MemoryMXBean getMemoryBean() {
        return memoryBean;
    }

    public List&lt;MemoryPoolMXBean&gt; getPoolList() {
        return poolList;
    }

    public Boolean getPollEnabled() {
        return pollEnabled;
    }

    public void setPollEnabled(Boolean pollEnabled) {
        this.pollEnabled = pollEnabled;
    }

    public Long getInterval() {
        return interval;
    }

    public void setInterval(Long interval) {
        this.interval = interval;
    }

    public Date getLastActualization() {
        return Calendar.getInstance().getTime();
    }

    public String getTimeZone() {
        return timeZone;
    }
}
</pre>
<p>Efekt:</p>
<p><a href="http://ludera.info/wp-content/uploads/2010/06/jvmMemoryMonitorWithRichfaces.png"><img class="aligncenter size-full wp-image-557" title="jvmMemoryMonitorWithRichfaces" src="http://ludera.info/wp-content/uploads/2010/06/jvmMemoryMonitorWithRichfaces.png" alt="" width="360" height="473" /></a></p>
<p>Jestem obecnie, jak pewnie wielu, na etapie rozpoznawania nowości w Java EE 6. Treningowo, postanowiłem zatem napisać ten sam JVM Monitor z wykorzystaniem <a title="Asynchronous processing support in Servlet 3.0" href="http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html" onclick="pageTracker._trackPageview('/outgoing/www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?referer=');">Asynchronious Processing Support z Servlets 3.0</a> &#8211; także wkrótce rozwinięcie tematu.</p>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/java/monitoring-podstawowych-parametrow-jvm-z-poziomu-web-aplikacji/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Vaadin vs Richfaces i o tym co z tego wyszło [Java EE 6, Maven, Glassfish, Oracle]</title>
		<link>http://ludera.info/java/vaadin-vs-richfaces-i-o-tym-co-z-tego-wyszlo-java-ee-6-maven-glassfish-oracle</link>
		<comments>http://ludera.info/java/vaadin-vs-richfaces-i-o-tym-co-z-tego-wyszlo-java-ee-6-maven-glassfish-oracle#comments</comments>
		<pubDate>Tue, 13 Apr 2010 22:40:51 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[addressbook]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[java ee 6]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[richfaces]]></category>
		<category><![CDATA[vaadin]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=529</guid>
		<description><![CDATA[Głośno ostatnio na DWorld i DZone zrobiło się o nowej odsłonie Vaadina &#8211; frameworku opartego na GWT. Nigdy wcześniej nie miałem styczności z GWT (prócz kilku tutoriali i paru hellowordów). Pracuję natomiast na codzień z JSF &#8211; najczęściej w implementacji Richfaces. Chciałem więc sprawdzić co potrafi ten rozchwalany na lewo i prawo Vaadin oraz jak [...]]]></description>
			<content:encoded><![CDATA[<p>Głośno ostatnio na<a title="Developers World" href="http://www.dworld.pl/" onclick="pageTracker._trackPageview('/outgoing/www.dworld.pl/?referer=');"> DWorld</a> i <a title="DZone" href="http://www.dzone.com/links/index.html" onclick="pageTracker._trackPageview('/outgoing/www.dzone.com/links/index.html?referer=');">DZone</a> zrobiło się o nowej odsłonie <a title="Vaadin" href="http://vaadin.com/home" onclick="pageTracker._trackPageview('/outgoing/vaadin.com/home?referer=');">Vaadina</a> &#8211; frameworku <strong>opartego </strong>na GWT. Nigdy wcześniej nie miałem styczności z GWT (prócz kilku tutoriali i paru hellowordów). Pracuję natomiast na codzień z JSF &#8211; najczęściej w implementacji <a title="JBoss Richfaces" href="http://www.jboss.org/richfaces" onclick="pageTracker._trackPageview('/outgoing/www.jboss.org/richfaces?referer=');">Richfaces</a>. Chciałem więc sprawdzić co potrafi ten rozchwalany na lewo i prawo Vaadin oraz jak jego zestaw gotowych komponentów ma się do Richfaces w kontekście budowania interfejsu użytkownika dla aplikacji &#8216;biznesowych&#8217; (tabele, modalpanele, itp, itd) w konwencji podbierania gotowych komponentów ze stron frameworków (odpowiednio <a title="Komponenty Vaadin" href="http://demo.vaadin.com/sampler/" onclick="pageTracker._trackPageview('/outgoing/demo.vaadin.com/sampler/?referer=');">tej</a> i <a title="Komponenty Richfaces" href="http://livedemo.exadel.com/richfaces-demo/index.jsp" onclick="pageTracker._trackPageview('/outgoing/livedemo.exadel.com/richfaces-demo/index.jsp?referer=');">tej</a>). Mam świadomość tego, że porównywanie Vaadina do Richfaces to jak zestawianie arbuzów z dyniami &#8211; za jedyne kryterium porównawcze chciałem zatem przyjąć ogólną prostotę danego rozwiązania. Chodziło o to żeby zrobić (CRUDa, a jakże) a się nie narobić <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Najprostszą metodą stworzenia działającego projektu Vaadin, jest <a title="Vaadin tutorial" href="http://vaadin.com/tutorial/-/page/project-setup.html" onclick="pageTracker._trackPageview('/outgoing/vaadin.com/tutorial/-/page/project-setup.html?referer=');">wyklikanie</a> go z poziomu Eclipse (kreatory i edytor WYSIWYG). Najłatwiejszą, jaką znam, metodą zbudowania projektu opartego o Richfaces jest <a title="Richfaces Livedemo sources" href="http://anonsvn.jboss.org/repos/richfaces/branches/community/3.3.X/samples/richfaces-demo/" onclick="pageTracker._trackPageview('/outgoing/anonsvn.jboss.org/repos/richfaces/branches/community/3.3.X/samples/richfaces-demo/?referer=');">pobranie przykładowej aplikacji</a> i wyrzucenie niepotrzebnych plików albo&#8230; wygenerowanie Seamowego projektu seam-gen&#8217;em. Można również oczywiście w obu przypadkach bawić się w Mavena.</p>
<p>Poznawanie Vaadina rozpocząłem właśnie od napisania sobie <a title="Vaadin tutorial" href="http://vaadin.com/tutorial/-/page/project-setup.html" onclick="pageTracker._trackPageview('/outgoing/vaadin.com/tutorial/-/page/project-setup.html?referer=');">AddressBook</a>&#8216;a &#8211; nic innego jak CRUD, który chciałem stworzyć samemu&#8230; Stwierdziłem więc, że może chociaż samemu dorzucę ORM (JPA) i zobaczę czy nadal wszystko będzie tak gładko chodzić, to też już ktoś wcześniej <a title="Vaadin AddressBook z JPA" href="http://vaadin.com/wiki/-/wiki/Main/Adding%20JPA%20to%20the%20Address%20Book%20Demo" onclick="pageTracker._trackPageview('/outgoing/vaadin.com/wiki/-/wiki/Main/Adding_20JPA_20to_20the_20Address_20Book_20Demo?referer=');">zrobił</a> <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Pomyślałem więc, że zbiorę chociaż wszystko to do kupy i sprawdzę czy się nie &#8216;gryzie&#8217;. Napisałem zatem mavenowy AddressBook z JPA, pracujący na Glassfish 3.1 z Oracle 10g Express Edition w tle &#8211; zadziałało. Poniżej listing jak wygenerować szablon <a title="Integracja Vaadin z Maven" href="http://vaadin.com/wiki/-/wiki/Main/Using%20Vaadin%20with%20Maven" onclick="pageTracker._trackPageview('/outgoing/vaadin.com/wiki/-/wiki/Main/Using_20Vaadin_20with_20Maven?referer=');">projektu Vaadina w mavenie</a>, oraz gotowy projekt do pobrania plus kilka podpowiedzi jak coś takiego uruchomić tudzież &#8216;napisać&#8217; samemu.</p>
<p>0) instalujemy i konfigurujemy Oracle 10g Express Edition</p>
<p>1) pobieramy najnowszego <a title="Latest NB Glassfish 3.1" href="http://download.java.net/glassfish/v3.1/nightly/latest-glassfish.zip" onclick="pageTracker._trackPageview('/outgoing/download.java.net/glassfish/v3.1/nightly/latest-glassfish.zip?referer=');">glassfisha 3.1</a> (wersja 3 zawiera bug niepozwalający na swobodne korzystanie z Vaadin &#8211; chodzi o ładowanie klas)</p>
<p>2) do $GLASSFISH_HOME/glassfish/lib dorzucamy sterownik ojdbc14.jar</p>
<p>3) z $GLASSFISH_HOME/bin uruchamiamy asadmin start domain &#8211; startujemy domyślną (domain1) domenę serwera wszystkorobiącym skryptem asadmin</p>
<p>4) otwieramy konsolę administracyjną Glassfisha (http://localhost:4848) i wybieramy z menu Resources-&gt;JDBC-&gt;JDBC Connection Pools</p>
<p>5) dodajemy pulę połączeń do naszej bazy</p>
<p style="text-align: center;"><a href="http://ludera.info/wp-content/uploads/2010/04/1.png"><img class="aligncenter size-full wp-image-534" title="Konfiguracja puli połączeń 1" src="http://ludera.info/wp-content/uploads/2010/04/1.png" alt="" width="337" height="113" /></a><a href="http://ludera.info/wp-content/uploads/2010/04/2.png"></a></p>
<p style="text-align: center;">
<p style="text-align: center;"><a href="../wp-content/uploads/2010/04/2.png"><img class="aligncenter" title="Konfiguracja puli połączeń 2" src="../wp-content/uploads/2010/04/2.png" alt="" width="367" height="95" /></a></p>
<p style="text-align: center;">
<p>6) dodajemy JDBC Recource (o nazwie jdbc/sample) dla skonfigurowanej przed chwilą puli połączeń &#8211; będziemy się do tego źródła danych odwoływać z poziomu aplikacji (w persistance.xml)</p>
<p>7) restartujemy serwer (asadmin stop-domain; asadmin start-domain)</p>
<p>8 ) generujemy projekt skryptem mvnAddressBook.sh:</p>
<pre class="brush: xml;">
#!/bin/bash
if [ &quot;$#&quot; -gt 2 ]
then
	groupId=$1
	artifactId=$2
else
	artifactId=AddressBook
	groupId=com.vaadin.demo.tutorial.addressbook
fi
mvn archetype:generate -DarchetypeGroupId=com.vaadin -DarchetypeArtifactId=vaadin-archetype-clean -DarchetypeVersion=LATEST -DgroupId=&quot;$groupId&quot; -DartifactId=&quot;$artifactId&quot; -Dversion=1.0 -Dpackaging=war
cd $artifactId; mvn eclipse:eclipse
</pre>
<p>9) importujemy projekt do Eclipse z zainstalowanym pluginem do Vaadina (dzięki temu będziemy mieć edytor WYSIWYG do składania GUI z klocków)</p>
<p>10) rozwiązanie zależności z Glassfish w pom.xml (po pobraniu projektu dołączonego do tego wpisu ustaw własną ścieżkę!)</p>
<p>11) teraz najważniejsze. według uznania, przechodzimy przez tutorial AddressBook i AddressBook+JPA pamiętając o hierarchii projektu narzuconej przez Maven lub <a title="Vaadin AddressBook z JPA - źródła" href="http://vaadin.com/c/wiki/get_page_attachment?p_l_id=35405&amp;nodeId=10674&amp;title=Adding+JPA+to+the+Address+Book+Demo&amp;fileName=Adding+JPA+to+the+Address+Book+Demo%2Faddressbook.tar.gz" onclick="pageTracker._trackPageview('/outgoing/vaadin.com/c/wiki/get_page_attachment?p_l_id=35405_amp_nodeId=10674_amp_title=Adding+JPA+to+the+Address+Book+Demo_amp_fileName=Adding+JPA+to+the+Address+Book+Demo_2Faddressbook.tar.gz&amp;referer=');">ściągamy</a> gotowy projekt i przerzucamy kod do naszego. Dodajemy również web.xml z pustą deklaracją &#8211; korzystamy z Java EE6, więc konfigurujemy serwlety adnotacjami &#8211; patrz AddressBookApplication (jak widać konfiguracja Vaadina jest właściwie zerowa,w odróżnieniu od JSF gdzie skazani jesteśmy na klepanie kilometrowych plików typu faces-config.xml)</p>
<p>12) dorzucamy katalogi src/test/resources i implementujemy testy jednostkowe! <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>13) mvn compile war:war</p>
<p>14) delpoy aplikacji z poziomu konsoli administracyjnej Glassfish (pozycja menu Applications), z Eclipsa lub <a href="https://maven-glassfish-plugin.dev.java.net/" onclick="pageTracker._trackPageview('/outgoing/maven-glassfish-plugin.dev.java.net/?referer=');">Mavenem</a>.</p>
<p style="text-align: center;"><a href="http://ludera.info/wp-content/uploads/2010/04/3.png"><img class="aligncenter size-full wp-image-536" title="AddressBook [Vaadin, Java EE6 (Servlets, EJB 3, JPA), Glassfish, Oracle DB]" src="http://ludera.info/wp-content/uploads/2010/04/3.png" alt="" width="380" height="552" /></a></p>
<p>Podsumowanie.</p>
<p>Nie pisałem ostatecznie analogicznej aplikacji w Seam (z Richfaces). Wiem bowiem jak coś takiego zrobić i jak świetnym narzędziem do generowania CRUDów jest seam-gen. Jeśli chodzi o Vaadin to muszę powiedzieć, że ten framework przegania pod względem prostoty JSF (nawet z tak świetnym zestawem komponentów jak Richfaces). Pisząc w Vaadin ani razu nie musimy zaglądać do web.xml, czy innych charakterystycznych dla frameworku xmli &#8211; i to jest świetne. Kuleje mocno edytor WYSIWYG &#8211; obecnie w fazie testów. Jak widać Vaadin da się zaprząc całokowicie bezboleśnie do współpracy z Java EE. Ciekaw natomiast jestem, czy da się (i czy jest sens) pożenić Vaadina z Seamem &#8211; ktoś próbował?</p>
<p>Wnioski.</p>
<p>Koniecznie zmienić skórkę dla bloga, bo się nie mieszczę!</p>
<p>PS. Jeszcze taka jedna obserwacja. Dzięki temu, że JSF podzielony jest na widok (jsp lub facelets) i kontroler (managed beans), ciężej niż w Vaadin jest napisać śmietnik zamiast kodu. Jedyne ryzyko, to to że nasze beany zamiast obiektowych będą kodem proceduralnym. Vaadin jest badzo podobny do Swinga, wypada więc <a href="http://en.wikipedia.org/wiki/Strategy_pattern" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Strategy_pattern?referer=');">strategicznie</a> <a href="http://en.wikipedia.org/wiki/Object_composition" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Object_composition?referer=');">komponować</a> kod zamiast uwailić całe GUI w metodzie init() <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Sugestie jak pisać czysty kod w Vaadin znaleźć można w samej aplikacji AddressBook oraz w Book of Vaadin (<a rel="nofollow" href="http://en.wikipedia.org/wiki/Book_of_Mormon" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Book_of_Mormon?referer=');">nie mylić z tym</a>) <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>PS2. Zapowiada się świetna okazja, by już <a href="http://groups.google.com/group/warszawa-jug/web/harmonogram-spotka-i-ich-tematy" onclick="pageTracker._trackPageview('/outgoing/groups.google.com/group/warszawa-jug/web/harmonogram-spotka-i-ich-tematy?referer=');">20.04.2010</a> posłuchać paru <a title="KoziołekWeb" href="http://koziolekweb.pl/2010/03/28/songs-of-vaadin/" onclick="pageTracker._trackPageview('/outgoing/koziolekweb.pl/2010/03/28/songs-of-vaadin/?referer=');">mądrych</a> słów o Vaadin. Ja z przyczyn obiektywnych niestety nie będę mógł skorzystać, niemniej jednak zapraszam bo na pewno warto!</p>
<p>Kompletny projekt do <a title="VaadinAddressbookWithJpaAndMaven.zip" href="http://ludera.info/files/VaadinAddressbookWithJpaAndMaven.zip">pobrania</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/java/vaadin-vs-richfaces-i-o-tym-co-z-tego-wyszlo-java-ee-6-maven-glassfish-oracle/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jak wyciągnąć kilka pierwszych wyników zapytania SQL</title>
		<link>http://ludera.info/it/jak-wyciagnac-kilka-pierwszych-wynikow-zapytania-sql</link>
		<comments>http://ludera.info/it/jak-wyciagnac-kilka-pierwszych-wynikow-zapytania-sql#comments</comments>
		<pubDate>Thu, 25 Mar 2010 22:27:27 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[it]]></category>
		<category><![CDATA[db2]]></category>
		<category><![CDATA[informix]]></category>
		<category><![CDATA[limit]]></category>
		<category><![CDATA[mssql]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[offset]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[postgre]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=521</guid>
		<description><![CDATA[-- Oracle select a.* from (select rownum row_num, t.* from t_table t ) a where a.row_num &#60;= N -- DB2 select * from t_table fetch first 10 rows only -- Informix select first 10 * from t_table -- PostgreSQL select * from table limit 10 -- MS SQL select top 10 * from table -- [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: sql;">
-- Oracle
select a.*
  from (select rownum row_num, t.*
          from t_table t
       ) a
 where a.row_num &lt;= N

-- DB2
select *
  from t_table
 fetch first 10 rows only

-- Informix
select first 10 *
  from t_table

-- PostgreSQL
select *
  from table limit 10

-- MS SQL
select top 10 *
  from table

-- MySQL
select *
  from table limit 10
</pre>
<p>Osobną sprawą jest stworzenie okna przydatnego do stronnicowania wyników zapytania. Wówczas składnia Oracle jest wg mnie najbardziej intuicyjna &#8211; używamy zwykłego ANSI SQL (beetween, operatory &gt;&lt; itp).</p>
<p>Inne bazy korzystają najczęściej z różnych wariacji słowa kluczowego offset lub limit z dwoma parametrami.</p>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/it/jak-wyciagnac-kilka-pierwszych-wynikow-zapytania-sql/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Vademecum IBM i oraz darmowe konto na iSeries</title>
		<link>http://ludera.info/ibm-i/vademecum-ibm-i-oraz-darmowe-konto-na-iseries</link>
		<comments>http://ludera.info/ibm-i/vademecum-ibm-i-oraz-darmowe-konto-na-iseries#comments</comments>
		<pubDate>Tue, 16 Mar 2010 14:51:37 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[ibm i]]></category>
		<category><![CDATA[as400]]></category>
		<category><![CDATA[iseries]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=502</guid>
		<description><![CDATA[Znalazłem jakiś czas temu &#8216;hosting&#8217; oparty o iSeries, na którym można założyć sobie darmowe konto. Gdyby ktoś zatem poczuł nieodpartą pokusę pobawienia się AS/400 Green Screen, to ma taką możliwość. Pod tym adresem, znajduje się natomiast niezła ściąga z obsługi OS/400.]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://ludera.info/wp-content/uploads/2010/03/ibm-i-for-dummies3.png"><img class="size-full wp-image-508 aligncenter" title="ibm-i-for-dummies" src="http://ludera.info/wp-content/uploads/2010/03/ibm-i-for-dummies3.png" alt="ibm-i-for-dummies" width="239" height="300" /></a></p>
<p style="text-align: left;">Znalazłem jakiś czas temu &#8216;hosting&#8217; oparty o iSeries, na którym można  założyć sobie <a title="Free iSeries Account" href="http://www.innovativesys.net/?page_id=19" onclick="pageTracker._trackPageview('/outgoing/www.innovativesys.net/?page_id=19&amp;referer=');">darmowe konto</a>. Gdyby ktoś zatem poczuł nieodpartą pokusę pobawienia się AS/400 Green Screen, to ma taką możliwość.</p>
<p>Pod <a title="OS/400 - vademecum" href="http://krypton.mnsu.edu/~j3gum/web/as400/intref.html" onclick="pageTracker._trackPageview('/outgoing/krypton.mnsu.edu/_j3gum/web/as400/intref.html?referer=');">tym</a> adresem, znajduje się natomiast niezła ściąga z obsługi OS/400.<span id="more-502"></span></p>
<p style="text-align: center;"><a href="http://ludera.info/wp-content/uploads/2010/03/free-tn5250.png"><img class="size-full wp-image-506     aligncenter" title="free-tn5250" src="http://ludera.info/wp-content/uploads/2010/03/free-tn5250.png" alt="Darmowe konto na iSeries" width="380" height="330" /></a></p>
<p style="text-align: left;">
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/ibm-i/vademecum-ibm-i-oraz-darmowe-konto-na-iseries/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zabezpieczony: Analiza pakietu programistycznego środowiska iSeries</title>
		<link>http://ludera.info/ibm-i/analiza-pakietu-programistycznego-srodowiska-iseries</link>
		<comments>http://ludera.info/ibm-i/analiza-pakietu-programistycznego-srodowiska-iseries#comments</comments>
		<pubDate>Mon, 15 Mar 2010 22:45:21 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[ibm i]]></category>
		<category><![CDATA[agh]]></category>
		<category><![CDATA[as400]]></category>
		<category><![CDATA[dariusz ludera]]></category>
		<category><![CDATA[ludera]]></category>
		<category><![CDATA[mgr]]></category>
		<category><![CDATA[system i]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=491</guid>
		<description><![CDATA[Brak wypisu, ponieważ wpis jest zabezpieczony hasłem.]]></description>
			<content:encoded><![CDATA[<form action="http://ludera.info/wp-pass.php" method="post">
<p>Ten wpis jest zabezpieczony hasłem. Aby go zobaczyć, proszę wprowadzić poniżej swoje hasło:</p>
<p><label for="pwbox-491">Hasło:<br />
<input name="post_password" id="pwbox-491" type="password" size="20" /></label><br />
<input type="submit" name="Submit" value="Wyślij" /></p></form>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/ibm-i/analiza-pakietu-programistycznego-srodowiska-iseries/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Singleton z double-checked locking oraz problem z wielowątkowością w TestNG</title>
		<link>http://ludera.info/java/singleton-z-double-checked-locking-oraz-problem-z-wielowatkowoscia-w-testng</link>
		<comments>http://ludera.info/java/singleton-z-double-checked-locking-oraz-problem-z-wielowatkowoscia-w-testng#comments</comments>
		<pubDate>Mon, 15 Mar 2010 21:39:00 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[double-checked locking]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[singleton]]></category>
		<category><![CDATA[testng]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=438</guid>
		<description><![CDATA[Wyczytałem ostatnio w mądrych książkach (tej i tej), że synchronizacja singletonów na poziomie całej metody getInstance może w środowisku wielowątkowym znacznie (25%) spowolnić pobieranie instancji obiektu przechowywanego przez owy singleton. W polskiej wikipedii ktoś napisał, że synchronizacja ta może obniżyć wydajność (w stosunku do metody niesynchronizowanej) o czynnik 100 lub więcej &#8211; szczerze, nie rozumiem [...]]]></description>
			<content:encoded><![CDATA[<p>Wyczytałem ostatnio w mądrych książkach (<a title="Effective Java Second Edition" href="http://java.sun.com/docs/books/effective/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/java.sun.com/docs/books/effective/?referer=');">tej</a> i <a title="Head First Design Patterns" href="http://helion.pl/ksiazki/hfdepa.htm" target="_blank" onclick="pageTracker._trackPageview('/outgoing/helion.pl/ksiazki/hfdepa.htm?referer=');">tej</a>), że synchronizacja singletonów na poziomie całej metody getInstance może w środowisku wielowątkowym znacznie (25%) spowolnić pobieranie instancji obiektu przechowywanego przez owy singleton. W polskiej <a href="http://pl.wikipedia.org/wiki/Blokada_z_podw%C3%B3jnym_zatwierdzeniem_%28wzorzec_projektowy%29" target="_blank" onclick="pageTracker._trackPageview('/outgoing/pl.wikipedia.org/wiki/Blokada_z_podw_C3_B3jnym_zatwierdzeniem_28wzorzec_projektowy_29?referer=');">wikipedii</a> ktoś napisał, że synchronizacja ta może obniżyć wydajność (w stosunku do metody niesynchronizowanej) o czynnik 100 lub więcej &#8211; szczerze, nie rozumiem co oznacza rzeczony &#8216;czynnik 100&#8242;&#8230;</p>
<p>W przypadku, gdy wydajność ma dla nas kluczowe znaczenie, do tworzenia singletonów zalecano stosowanie wzorca double-checked locking (blokada z podwójnym zatwierdzaniem). Postanowiłem więc sprawdzić doświadczalnie jak w rzeczywistości wygląda spadek wydajności metod synchronizowanych. Napisałem więc trzy singletony:</p>
<p>tradycyjny</p>
<pre class="brush: java;">package info.ludera.SingletonPerformance.action.impl;

import info.ludera.SingletonPerformance.action.TestSingleton;

/**
 * Singleton z ZAWSZE synchronizowaną metodą {@link SimpleSingleton#getInstance()}
 * @author darekl
 *
 */
public class SimpleSingleton extends TestSingleton {

	/**
	 * Jedyna instancja obiektu {@link SimpleSingleton}
	 */
	private static SimpleSingleton instance;

	/**
	 * Konstruktor domyślny
	 */
	private SimpleSingleton() {
		super();
	}

	/**
	 * Zwraca instancję obiektu  {@link SimpleSingleton}
	 * @return
	 */
	public static synchronized SimpleSingleton getInstance() {

		if (instance == null) {
			instance = new SimpleSingleton();
		}
		return instance;
	}
}
</pre>
<p>i dwie różne implementacje double-checked locking:</p>
<p>&#8220;podstawowa&#8221;</p>
<pre class="brush: java;">package info.ludera.SingletonPerformance.action.impl;

import info.ludera.SingletonPerformance.action.TestSingleton;

/**
 * Singleton z synchronizowaną metodą {@link SimpleSingleton#getInstance()}. Synchronizacja aktywna jest tylko przy pierwszym uruchomieniu tej metody.
 * @author darekl
 *
 */
public class ThreadSaveSingleton extends TestSingleton {

	/**
	 * Jedyna instancja obiektu {@link SimpleSingleton}
	 */
	private volatile static ThreadSaveSingleton instance = null;

	/**
	 * Konstruktor domyślny
	 */
	private ThreadSaveSingleton() {
		super();
	}

	/**
	 * Zwraca instancję obiektu  {@link SimpleSingleton}
	 * @return
	 */
	public static ThreadSaveSingleton getInstance() {

		if (instance == null) {
			synchronized (ThreadSaveSingleton.class) {
				if (instance == null) {
					instance = new ThreadSaveSingleton();
				}
			}
		}
		return instance;
	}
}
</pre>
<p>i &#8220;<a href="http://technology.amis.nl/blog/4384/the-double-checked-locking-confusion" target="_blank" onclick="pageTracker._trackPageview('/outgoing/technology.amis.nl/blog/4384/the-double-checked-locking-confusion?referer=');">rozszerzona</a>&#8221;</p>
<pre class="brush: java;">package info.ludera.SingletonPerformance.action.impl;

import info.ludera.SingletonPerformance.action.TestSingleton;

/**
 * Singleton z synchronizowaną metodą {@link SimpleSingleton#getInstance()}. Synchronizacja aktywna jest tylko przy pierwszym uruchomieniu tej metody.
 * @author darekl
 *
 */
public class AdvancedThreadSaveSingleton extends TestSingleton {

	/**
	 * Jedyna instancja obiektu {@link SimpleSingleton}
	 */
	private volatile static AdvancedThreadSaveSingleton instance = null;

	/**
	 * Konstruktor domyślny
	 */
	private AdvancedThreadSaveSingleton() {
		super();
	}

	/**
	 * Zwraca instancję obiektu  {@link SimpleSingleton}
	 * @return
	 */
	public static AdvancedThreadSaveSingleton getInstance() {

		AdvancedThreadSaveSingleton result = instance;
		if (result == null) {
			synchronized (AdvancedThreadSaveSingleton.class) {
				result = instance;
				if (result == null) {
					instance = result = new AdvancedThreadSaveSingleton();
				}
			}
		}
		return result;
	}
}
</pre>
<p>Przetestowałem ich działanie poniższym testem dla różnej ilości wątków (100-100000):</p>
<pre class="brush: java;">package info.ludera.SingletonPerformance.test;

...

public class FabricMultiThreadSingletonTest extends AbstractSingletonTest {

	@DataProvider
	public Object[][] ValidJavaVersion() {

		return new Object[][]{
				{ 5 }
		};
	}

	/**
	 * Ilość iteracji
	 */
	protected static Long testCounter;

	/**
	 * Prefix nazwy wątku
	 */
	protected static String threadNamePrefix = &quot;Thread_&quot;;

	@BeforeClass
	@Parameters(value=&quot;repetitionQuantity&quot;)
	public void setTestCounter(long repetitionQuantity) {
		testCounter = repetitionQuantity;
	}

	@Test
	public void getSimpleSingletonNTimes() {

		for (long i=0; i&lt;testCounter; i++) {
			SingletonFactory simpleSingletonFactory = new SimpleSingletonFactory(threadNamePrefix + i);
			simpleSingletonFactory.start();
		}
	}

	@Test(dataProvider = &quot;ValidJavaVersion&quot;)
	public void getThreadSaveSingletonNTimes(final int javaVersion) {

		//Assert.assertTrue((Integer.parseInt(&quot;&quot; + System.getProperty(&quot;java.version&quot;).charAt(2)) &gt;= javaVersion), &quot;This test is avialable only with Java 5 or above!&quot;);

		for (long i=0; i&lt;testCounter; i++) {
			SingletonFactory threadSaveSingletonFactory = new ThreadSaveSingletonFactory(threadNamePrefix + i);
			threadSaveSingletonFactory.start();
		}
	}

	@Test(dataProvider = &quot;ValidJavaVersion&quot;)
	public void getAdvencedThreadSaveSingletonNTimes(final int javaVersion) {

		//Assert.assertTrue((Integer.parseInt(&quot;&quot; + System.getProperty(&quot;java.version&quot;).charAt(2)) &gt;= javaVersion), &quot;This test is avialable only with Java 5 or above!&quot;);

		for (long i=0; i&lt;testCounter; i++) {
			SingletonFactory advancedThreadSaveSingletonFactory = new AdvancedThreadSaveSingletonFactory(threadNamePrefix + i);
			advancedThreadSaveSingletonFactory.start();
		}
	}
}
</pre>
<p>I rzeczywiście. Czasowe wyniki działania tych testów, dla różnej ilości iteracji, rozchodziły się w słuszną stronę. Wraz ze wzrostem iteracji, SimpleSingleton działał coraz wolniej w stosunku do wersji z double-checked locking. Testy przeprowadzałem na JDK 1.6.0_16 oraz JDK 1.5.0_22. Nie testowałem wydajności na Java 1.4. Istnieje bowiem prawdopodobieństwo wystąpienia problemu błędnej implementacji volatile. Oto przykładowe wyniki dla 10000 iteracji na JDK 1.6:</p>
<pre>getSimpleSingletonNTimes - 1624ms
getThreadSaveSingletonNTimes - 1209ms
getAdvencedThreadSaveSingletonNTimes - 1153ms</pre>
<p>To nie wszystko. Po zastanowieniu, doszedłem do wniosku, że użycie wzorca fabryki do  takich teścików to przerost formy nad treścią. Stwierdziłem więc, że wykorzystam wielowątkowości z TestNG.</p>
<p>oto test:</p>
<pre class="brush: java;">package info.ludera.SingletonPerformance.test;

...

import org.testng.annotations.Test;

/**
 * Test wydajności synchronizacji singletonów {@link info.ludera.SingletonPerformance.test.helper.SimpleSingletonFactory} i {@link info.ludera.SingletonPerformance.test.helper.ThreadSaveSingletonFactory}
 * @author darekl
 *
 */
public class MultiThreadSingletonTest extends AbstractSingletonTest {

	@Test(threadPoolSize=1000, invocationCount = 1000)
	public void getSimpleSingleton() {

		SimpleSingleton.getInstance();
	}

	@Test(dataProvider = &quot;ValidJavaVersion&quot;, threadPoolSize=1000, invocationCount = 1000)
	public void getThreadSaveSingleton(final int javaVersion) {

		//Assert.assertTrue((Integer.parseInt(&quot;&quot; + System.getProperty(&quot;java.version&quot;).charAt(2)) &gt;= javaVersion), &quot;This test is avialable only with Java 5 or above!&quot;);

		ThreadSaveSingleton.getInstance();
	}

	@Test(dataProvider = &quot;ValidJavaVersion&quot;, threadPoolSize=1000, invocationCount = 1000)
	public void getAdvencedThreadSaveSingleton(final int javaVersion) {

		//Assert.assertTrue((Integer.parseInt(&quot;&quot; + System.getProperty(&quot;java.version&quot;).charAt(2)) &gt;= javaVersion), &quot;This test is avialable only with Java 5 or above!&quot;);

		AdvancedThreadSaveSingleton.getInstance();
	}
}
</pre>
<p>i wyniki (tym razem dla 1000 wątków):</p>
<pre>getSimpleSingletonNTimes - 110ms
getThreadSaveSingletonNTimes - 97ms
getAdvencedThreadSaveSingletonNTimes - 100ms
getSimpleSingleton - 716ms
getThreadSaveSingleton - 2050ms
getAdvencedThreadSaveSingleton - 2079ms</pre>
<p>Zastanawiające. Dlaczego trzy ostatnie testy (te dopisane powyżej) nie układają się tak jak te poprzednie, gdzie wielowątkowość napisałem ręcznie? Dlaczego widać tak duże różnice w wydajności? Przyznam szczerze, że z wielowątkowości w TestNG korzystam po praz pierwszy, czy ktoś bardziej doświadczony w tym temacie, mógłby mi wyjaśnić w czym tkwi problem na który się natknąłem i co robię źle?</p>
<p><a title="SingletonPerformance.zip" href="http://ludera.info/files/SingletonPerformance.zip">Pobierz</a> projekt eclipse (wymagania: Maven2 lub Eclipse z pluginami: <a title="m2eclipse" href="http://m2eclipse.sonatype.org/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/m2eclipse.sonatype.org/?referer=');">m2eclipse</a> i <a title="TestNG Eclipse Plugin" href="http://testng.org/doc/index.html#locations-projects" target="_blank" onclick="pageTracker._trackPageview('/outgoing/testng.org/doc/index.html_locations-projects?referer=');">TestNG</a>)</p>
<p>PS. Apropos optymalizacji kodu pod względem jego wydajności, polecam <a title="Dlaczego moje optymalizacje nie optymalizują? " href="http://www.devblogi.pl/2010/03/dlaczego-moje-optymalizacje-nie.html" onclick="pageTracker._trackPageview('/outgoing/www.devblogi.pl/2010/03/dlaczego-moje-optymalizacje-nie.html?referer=');">ten</a> artykuł. Po jego przeczytaniu nasunęła mi się analogia dotycząca RDBMS i hintów oraz przesiadki z optymalizatorów regułowych na kosztowe <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;">
<p>package info.ludera.SingletonPerformance.action.impl;</p>
<p>import info.ludera.SingletonPerformance.action.TestSingleton;</p>
<p>/**<br />
* Singleton z ZAWSZE synchronizowaną metodą {@link SimpleSingleton#getInstance()}<br />
* @author darekl<br />
*<br />
*/<br />
public class SimpleSingleton extends TestSingleton {</p>
<p>/**<br />
* Jedyna instancja obiektu {@link SimpleSingleton}<br />
*/<br />
private static SimpleSingleton instance;</p>
<p>/**<br />
* Konstruktor domyślny<br />
*/<br />
private SimpleSingleton() {<br />
super();<br />
}</p>
<p>/**<br />
* Zwraca instancję obiektu  {@link SimpleSingleton}<br />
* @return<br />
*/<br />
public static synchronized SimpleSingleton getInstance() {</p>
<p>//System.out.println(&#8220;SimpleSingleton.getInstance start for &#8221; + Thread.currentThread().getName());<br />
if (instance == null) {<br />
instance = new SimpleSingleton();<br />
}<br />
//System.out.println(&#8220;SimpleSingleton.getInstance stop  for &#8221; + Thread.currentThread().getName());<br />
return instance;<br />
}<br />
}</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/java/singleton-z-double-checked-locking-oraz-problem-z-wielowatkowoscia-w-testng/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Alior Bank assistance</title>
		<link>http://ludera.info/live/alior-bank-assistance</link>
		<comments>http://ludera.info/live/alior-bank-assistance#comments</comments>
		<pubDate>Mon, 08 Mar 2010 07:49:56 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[live]]></category>
		<category><![CDATA[alior]]></category>
		<category><![CDATA[assistance]]></category>
		<category><![CDATA[pomoc drogowa]]></category>
		<category><![CDATA[pomocni fachowcy]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=430</guid>
		<description><![CDATA[Miałem przed chwilą okazję przetestować w działaniu pakiet Pomocni Fachowcy, który Alior Bank z Mondial Assistance zaproponował ostatnio swoim klientom. Potrzebowałem mianowicie pomocy drogowej. Poniżej przebieg akcji &#8216;reanimacja-mojego-auta&#8217;: 6.30 &#8211; telefon na jak się okazało przeznaczoną specjalnie dla klientów Aliora Infolinię Assistance (tel. 0048 22 563 11 15). O dziwo nie zaspana Pani odebrała ode [...]]]></description>
			<content:encoded><![CDATA[<p>Miałem przed chwilą okazję przetestować w działaniu pakiet <a title="Alior Bank Assistance" href="http://konto-z-lokata-nocna.aliorbank.pl/assistance.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/konto-z-lokata-nocna.aliorbank.pl/assistance.html?referer=');">Pomocni Fachowcy</a>, który <a title="Alior Bank" href="http://www.aliorbank.pl/pl/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.aliorbank.pl/pl/?referer=');">Alior Bank</a> z <a title="Mondial Assistance" href="http://www.mondial-assistance.pl/pl/aboutus/homepage.htm" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.mondial-assistance.pl/pl/aboutus/homepage.htm?referer=');">Mondial Assistance</a> zaproponował ostatnio swoim klientom. Potrzebowałem mianowicie pomocy drogowej. Poniżej przebieg akcji &#8216;reanimacja-mojego-auta&#8217;:</p>
<p><strong>6.30</strong> &#8211; telefon na jak się okazało przeznaczoną specjalnie dla klientów <a title="Pomocni Fachowcy - szczegóły pakietu" href="http://www.aliorbank.pl/pl/klienci_indywidualni/konta_osobiste/konto_z_lokata_nocna/assistance" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.aliorbank.pl/pl/klienci_indywidualni/konta_osobiste/konto_z_lokata_nocna/assistance?referer=');">Aliora Infolinię Assistance</a> (tel. 0048 22 563 11 15). O dziwo nie zaspana Pani odebrała ode mnie podstawowe dane i poinformowała, że po mojej autentykacji i autoryzacji do skorzystania z tego pakietu do mnie &#8216;czemprędzej&#8217; oddzwoni.</p>
<p><strong>6.35</strong> &#8211; obiecany telefon od Pani (plus gratisowa walidacja czy nie pomyliłem swojego numeru telefonu podczas poprzedniej rozmowy <img src='http://ludera.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Powiedziałem co się stało, gdzie jestem itp. Zostałem poinformowany, że pomoc drogowa powinna się ze mną wkrótce skontaktować.</p>
<p><strong>6.45</strong> &#8211; telefon od pomocy drogowej, ustalenie znaków rozpoznawczych itp itd. Pomoc będzie za godzinę bo są korki.</p>
<p><strong>7.40</strong> &#8211; telefon z pomocy drogowej, żebym ruszył cztery litery na parking bo już są.</p>
<p><strong>7.42 &#8211; 8.00</strong> &#8211; kilka uderzeń młotkiem, parę bujnięć samochodem, kilka mocnych szarpnięć za drążek do hamulca ręcznego &#8211; wszystko jak się okazało skutecznie. Co fachura to fachura <img src='http://ludera.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>8.00</strong> &#8211; la grande finale. Zero papierków, uścisk dłoni i po sprawie.</p>
<p>PS. Piszę to, bo nigdy w życiu nie korzystałem z takich &#8216;darmowych bonusów do różnych produktów na czarną godzinę&#8217; i sądziłem, że jeśli coś jest za darmo to i jakość jest&#8230; średnia. Jak się okazało firma <a title="Mondial Assistance" href="http://www.mondial-assistance.pl/pl/aboutus/homepage.htm" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.mondial-assistance.pl/pl/aboutus/homepage.htm?referer=');">Mondial</a> i partnerzy w terenie dają radę! Do niemiłego następnego.</p>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/live/alior-bank-assistance/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JSF &#8211; automatyczna zamiana null na 0 lub pusty string</title>
		<link>http://ludera.info/java/jsf-automatyczna-zamiana-null-na-0-lub-pusty-string</link>
		<comments>http://ludera.info/java/jsf-automatyczna-zamiana-null-na-0-lub-pusty-string#comments</comments>
		<pubDate>Tue, 19 Jan 2010 12:09:50 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[coerce to zero]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=416</guid>
		<description><![CDATA[Myślalem, że JSF nie ma już przede mną większych tajemnic, gdy w projekcie objawił się nam następujący błąd: JSF domyślnie z automatu zamienia formularzowe puste inputy na odpowiadające im 0 lub puste stringi. Inaczej mówiąc jeśli użytkownik do takiego inputTextu nic nie wpisze to referencja age zamiast być pusta (null) wskazywać będzie na 0. &#60;h:inputText [...]]]></description>
			<content:encoded><![CDATA[<p>Myślalem, że JSF nie ma już przede mną większych tajemnic, gdy w projekcie objawił się nam następujący błąd:</p>
<p>JSF domyślnie z automatu zamienia formularzowe puste inputy na odpowiadające im 0 lub puste stringi. Inaczej mówiąc jeśli użytkownik do takiego inputTextu nic nie wpisze to referencja age zamiast być pusta (null) wskazywać będzie na 0.</p>
<p><code>&lt;h:inputText id="age"<br />
value="#{exampleManager.age}" converter="IntegerConverter" /&gt;</code></p>
<p>Gdyby age było Stringiem, wówczas JSF przypisałby pod niego &#8220;&#8221;.</p>
<p>Rozwiązanie tego &#8216;problemu&#8217; okazało się trywialne choć dziwne (stąd ta notka). Należało zmienić domyślną wartość <a href="http://tomcat.apache.org/tomcat-6.0-doc/config/systemprops.html" onclick="pageTracker._trackPageview('/outgoing/tomcat.apache.org/tomcat-6.0-doc/config/systemprops.html?referer=');">flagi Tomcata COERCE_TO_ZERO</a> poprzez ustawienie odpowiedniego parametru uruchomieniowego:</p>
<p><code>-Dorg.apache.el.parser.COERCE_TO_ZERO=false</code></p>
<p>Domyślna wartość COERCE_TO_ZERO ustawiona jest na true. Oczywiście można tego dokonać również z poziomu kodu aplikacji &#8211; jak dla mnie rozwiązanie takie jest dużo bardziej elastyczne i eleganckie:</p>
<p><code>System.getProperties().<br />
put("org.apache.el.parser.COERCE_TO_ZERO", "false");</code></p>
<p>Projekt w którym objawił się ten problem pracuje na JBossie (posiadającym w sobie Tomcata), jak aplikacja ta zachowała by się na innych serwerach aplikacyjnych i jak wówczas poradzić sobie z opisywanym &#8216;wymuszaniem&#8217; &#8211; kiedyś może się dowiem&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/java/jsf-automatyczna-zamiana-null-na-0-lub-pusty-string/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mgr inż. Dariusz Ludera &#8230;</title>
		<link>http://ludera.info/cv/mgr-inz-dariusz-ludera</link>
		<comments>http://ludera.info/cv/mgr-inz-dariusz-ludera#comments</comments>
		<pubDate>Tue, 29 Dec 2009 20:53:19 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[Cv]]></category>
		<category><![CDATA[agh]]></category>
		<category><![CDATA[as400]]></category>
		<category><![CDATA[dariusz ludera]]></category>
		<category><![CDATA[ibm i]]></category>
		<category><![CDATA[ludera]]></category>
		<category><![CDATA[mgr]]></category>
		<category><![CDATA[system i]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=386</guid>
		<description><![CDATA[&#8230;brzmi dumnie 16 września 2009 udało mi się obronić moją pracę magisterską i jednocześnie uzyskać tytuł zawodowy magistra inżyniera. Tematem mojej pracy mgr była Analiza pakietu programistycznego środowiska iSeries (System i Development Environment Analysis). W ramach niniejszej pracy poddałem analizie dostępne na rynku narzędzia programistyczne na platformę IBM i. Oprócz opisu technologii programistycznych możliwych do [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;brzmi dumnie <img src='http://ludera.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  16 września 2009 udało mi się obronić moją pracę magisterską i jednocześnie uzyskać tytuł zawodowy magistra inżyniera. Tematem mojej pracy mgr była Analiza pakietu programistycznego środowiska <a title="IBM i" href="http://www-03.ibm.com/systems/i/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www-03.ibm.com/systems/i/?referer=');">iSeries</a> (<a title="IBM i" href="http://www-03.ibm.com/systems/i/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www-03.ibm.com/systems/i/?referer=');">System i</a> Development Environment Analysis).</p>
<p>W ramach niniejszej pracy poddałem analizie dostępne na rynku narzędzia programistyczne na platformę <a title="IBM i" href="http://www-03.ibm.com/systems/i/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www-03.ibm.com/systems/i/?referer=');">IBM i</a>. Oprócz opisu technologii programistycznych możliwych do wykorzystania na tejże platformie, skupiłem się na dokonaniu charakterystyki narzędzi wspomagających pracę przy tworzeniu nowych i rozwijaniu wcześniej stworzonych aplikacji. Praca miała na celu przeanalizowanie zakresu wykorzystania poszczególnych narzędzi, które mogą być używane w procesie wytwarzania aplikacji oraz odpowiedzenie na pytanie czy technologie i narzędzia stworzone kilka dekad temu nadają się do wykorzystania podczas budowania systemów zgodnych z dzisiejszymi standardami (głównie z podejściem <a title="Service Oriented Architecture" href="http://www-01.ibm.com/software/solutions/soa/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www-01.ibm.com/software/solutions/soa/?referer=');">SOA</a>). Analizie poddano podejście firmy IBM do rozwoju swoich narzędzi i środowisk programistycznych ułatwiających pracę programistów związanych z tworzeniem aplikacji zarówno w nowych, jak i starych technologiach. Przy opisie poszczególnych technologii, dokonałem oceny stosowalności każdej z nich w aplikacjach tworzonych obecnie na potrzeby sektora finansowego i bankowego. W końcowej części niniejszej pracy pokusiłem się o znalezienie optymalnego narzędzia dla programistów i podanie zestawu najlepszych moim zdaniem technologii, które połączone ze sobą, stanowić będą podstawę do tworzenia oprogramowania dla wyżej wymienionych sektorów, dla których dedykowana jest niniejsza platforma.</p>
<p>Nadmienię jeszcze tylko, iż praca ta realizowana była we współpracy (i właściwie na zamówienie) <a title="Fortis Bank Polska" href="http://www.bnpparibasfortis.pl/index.htm" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.bnpparibasfortis.pl/index.htm?referer=');">Fortis Bank Polska SA</a>.</p>
<p><span style="text-decoration: line-through;">Jeśli moja <a title="Akademia Górniczo-Hutnicza w Krakowie" href="http://agh.edu.pl/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/agh.edu.pl/?referer=');">Alma Mater</a> zrezygnuje z prawa do<a title="Praca magisterska - prawa autorskie" href="http://prawo.vagla.pl/node/7687" target="_blank" onclick="pageTracker._trackPageview('/outgoing/prawo.vagla.pl/node/7687?referer=');"> pierwodruku</a>, opublikuję ją z pewnością (najwcześniej 16.03.2010r) na łamach tej strony</span>. Pracę można pobrać <a title="Skorzystaj z formularza kontaktowego aby uzyskać hasło" href="http://ludera.info/ibm-i/analiza-pakietu-programistycznego-srodowiska-iseries">stąd</a>. Myślę, że może ona przydać się komuś kto został postawiony przed zadaniem poznania nowoczesnych webowych technologii dla IBM i. Oprócz bowiem wspomnianego wcześniej przeglądu technologii, stworzyłem 6 aplikacji w tych technologiach i pokazałem jak wdrożyć je w zwirtualizowanym środowisku IBM i.</p>
<p><strong>Lista aplikacji:</strong></p>
<ol>
<li> <strong>CL1.CLLE</strong> – prezentacja możliwości języka CL jako podstawowego narzędzia programistycznego umożliwiającego manipulację na obiektach i5/OS oraz danych zgromadzonych w zintegrowanej z i5/OS relacyjnej bazie danych DB2.
<ul>
<li><em>funkcjonalność</em> – wykonanie zadanego w parametrach uruchomieniowych skryptu SQL (SQLSRC47) z instrukcjami DDL i DML</li>
<li><em>wykorzystane technologie</em> – CL, SQL</li>
</ul>
</li>
<li> <strong>RPG1.SQLRPGLE</strong> – pokazanie składni języka RPG, której wykorzystanie zalecane jest obecnie przez IBM.
<ul>
<li><em>funkcjonalność</em> – insert do bazy danych w fixed-format, odczytanie zawartości tabeli CUSTOMER w free-format</li>
<li><em>wykorzystane technologie</em> – zagnieżdżenie poleceń SQL w obu wyżej wymienionych rodzajach składni RPG</li>
</ul>
</li>
<li> <strong>RiaExample </strong>
<ul>
<li> a) prezentacja technologii związanych z JEE, które stanowić mogą alternatywę dla RPG jeśli chodzi o implementację aplikacji zawierającej logikę biznesową opartą na danych zgromadzonych w bazie danych DB2 for i5/OS.</li>
<li> b) pokazanie technologii BIRT jako alternatywy dla RPG jeśli chodzi o generowanie biznesowych raportów dla potrzeb przedsiębiorstwa.
<ul>
<li> <em>funkcjonalność</em> – aplikacja posiada dwa moduły:
<ul>
<li> CRUD – pozwalający na podgląd i modyfikację danych z DB2 for i5/OS</li>
<li> raporty – pozwalający na generowanie raportów do HTML, PDF, MS Word i MS Excel</li>
</ul>
</li>
<li> <em>wykorzystane technologie</em> – aplikacja stworzona została w modelu RIA z wykorzystaniem następujących technologii: JSP, serwety, JS, zestaw komponentów JSF RichFaces, JDBC w implementacji JTOpen, Apache log4j, Eclipse BIRT</li>
</ul>
</li>
</ul>
</li>
<li> <strong>WsRiaExample</strong> – stworzenie tej aplikacji, miało na celu zaprezentowanie technologii Web Services, mogącej posłużyć do zbudowania architektury softwarowej zgodnej z metodologią SOA, opartej o IBM i.
<ul>
<li> <em>funkcjonalność</em> – wystawianie usług związanych z pobieraniem i obróbką danych z DB2 for i5/OS</li>
<li> <em>wykorzystane technologie</em> – Apache Axis2 z modułami zapewniającymi bezpieczeństwo wysyłanych komunikatów: WS-Security (Rampart) i WS-Addressing</li>
</ul>
</li>
<li> <strong>RichClientExample </strong>
<ul>
<li> a) przykład podejścia do tworzenia aplikacji biznesowych przed upowszechnieniem się J2EE</li>
<li> b) przykład kienta konsumującego usługi Web Services.
<ul>
<li> <em>funkcjonalność</em> – aplikacja posiada dwa moduły:
<ul>
<li> program typu Rich Client, realizujący <em>funkcjonalność</em> CRUD</li>
<li> klient odpytujący o dane Web Service z aplikacji numer 4.</li>
</ul>
</li>
</ul>
</li>
<li> <em>wykorzystane technologie</em> – J2SE, Swing, Apache Axis2, Apache log4j</li>
</ul>
</li>
<li> <strong>GrailsRiaExample</strong>
<ul>
<li> a) pokazanie, że na IBM i da się uruchamiać aplikacje zaimplementowane w nowoczesnych, dynamicznych, skryptowych językach programowania, wspomagających biznes dzięki którym możliwe jest ekspresowe tworzenie lekkich serwisów internetowych, przydatnych np. w marketingu nowych produktów (w tym finasowych)</li>
<li> b) przykład obudowania technologii znakowych aplikacją z webowym interfejsem użytkownika
<ul>
<li> <em>funkcjonalność</em>
<ul>
<li>webowa aplikacja realizująca <em>funkcjonalność</em> CRUD</li>
<li>o refacing komend języka CL</li>
</ul>
</li>
<li> <em>wykorzystane technologie</em> – Groovy, Grails, pluginy Grails: grails400utils, jtopen</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>Praca ta (a zwłaszcza rozdział 1.)  może być także moim zdaniem przydatna dla osób, które dopiero zaczynają przygodę z platformą IBM i i poszukują rzetelnych informacji na jej temat.</p>

<a href="http://ludera.info/wp-content/gallery/mecv/ludera_dariusz_dyplom_ukonczenia_studiow.jpg" title="Dariusz Ludera - dyplom ukończenia studiów" class="shutterset_singlepic37" >
	<img class="ngg-singlepic ngg-center" src="http://ludera.info/wp-content/gallery/cache/37__320x240_ludera_dariusz_dyplom_ukonczenia_studiow.jpg" alt="ludera_dariusz_dyplom_ukonczenia_studiow" title="ludera_dariusz_dyplom_ukonczenia_studiow" />
</a>

]]></content:encoded>
			<wfw:commentRss>http://ludera.info/cv/mgr-inz-dariusz-ludera/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IBM EGL fail</title>
		<link>http://ludera.info/ibm-i/ibm-egl-fail</link>
		<comments>http://ludera.info/ibm-i/ibm-egl-fail#comments</comments>
		<pubDate>Sun, 13 Sep 2009 09:12:06 +0000</pubDate>
		<dc:creator>Dariusz Ludera</dc:creator>
				<category><![CDATA[ibm i]]></category>
		<category><![CDATA[i5]]></category>
		<category><![CDATA[iseries]]></category>
		<category><![CDATA[system i5]]></category>

		<guid isPermaLink="false">http://ludera.info/?p=332</guid>
		<description><![CDATA[IBM jest obecnie na etapie lansowania technologii EGL, umożliwiającej tworzenie webowych aplikacji RIA dla IBM i. W telegraficznym skrócie jest to zlepek generatorów kodu Java, Java Script i COBOL. Na stronach EGL Caffe tworzony jest blog pokazujący &#8220;możliwości&#8221; tej technologii. Jak widać z tego przykładu, stosunek ilości wygenerowanego kodu Java Script do jego funkcjonalności jest [...]]]></description>
			<content:encoded><![CDATA[<p>IBM jest obecnie na etapie lansowania technologii <a title="EGL Reference Guide" href="http://publib.boulder.ibm.com/infocenter/iadthelp/v6r0/index.jsp?topic=/com.ibm.etools.iseries.egl.doc/eglguidewdsc02.htm" target="_blank" onclick="pageTracker._trackPageview('/outgoing/publib.boulder.ibm.com/infocenter/iadthelp/v6r0/index.jsp?topic=/com.ibm.etools.iseries.egl.doc/eglguidewdsc02.htm&amp;referer=');">EGL</a>, umożliwiającej tworzenie webowych aplikacji RIA dla IBM i. W telegraficznym skrócie jest to zlepek generatorów kodu Java, Java Script i COBOL.</p>
<p>Na stronach <a title="EGL Caffe" href="http://www-949.ibm.com/software/rational/cafe/community/egl" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www-949.ibm.com/software/rational/cafe/community/egl?referer=');">EGL Caffe</a> tworzony jest <a title="EGL Blog" href="http://www-949.ibm.com/software/rational/cafe/blogs/egl-i/2009/09/12/see-what-i-can-do-v2r1-complete" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www-949.ibm.com/software/rational/cafe/blogs/egl-i/2009/09/12/see-what-i-can-do-v2r1-complete?referer=');">blog</a> pokazujący &#8220;możliwości&#8221; tej technologii. Jak widać z <a title="EGL przykład użycia" href="http://see-what-i-can-do.com/poll2.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/see-what-i-can-do.com/poll2.html?referer=');">tego przykładu</a>, stosunek ilości wygenerowanego kodu Java Script do jego funkcjonalności jest delikatnie mówiąc dużo za duży!</p>
<p>Mam wrażenie, że cały ten EGL to przerost formy nad treścią. Bez komentarza pozostawiam pomysł stworzenia technologii, która ma w domyśle zastąpić RPG poprzez generowanie kodu COBOL, a do tego sprowadza się użycie EGL na iSeries.</p>
]]></content:encoded>
			<wfw:commentRss>http://ludera.info/ibm-i/ibm-egl-fail/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
