<?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>Marc "Slyoldfox" Vanbrabant</title>
	<atom:link href="http://marc.blog.foreach.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://marc.blog.foreach.com</link>
	<description>Ramblings about ICT Consultancy</description>
	<lastBuildDate>Fri, 29 Jul 2011 13:53:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>iTunes Connect sales report script in c#</title>
		<link>http://marc.blog.foreach.com/2010/07/itunes-connect-sales-report-script-in-c/</link>
		<comments>http://marc.blog.foreach.com/2010/07/itunes-connect-sales-report-script-in-c/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 08:23:31 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://marc.blog.foreach.com/?p=15</guid>
		<description><![CDATA[We needed to pump (or pimp) our BI environment with some sales data from the downloads of a recently released iPhone App. In order to do that I found the follow python script which worked just fine: http://code.google.com/p/appdailysales/. Now since we have a Microsoft SSIS environment, I ported (part) of this code to C# so [...]]]></description>
			<content:encoded><![CDATA[<p>We needed to pump (or pimp) our<strong> BI environment</strong> with some sales data from the downloads of a recently released iPhone App. In order to do that I found the follow python script which worked just fine: <a href="http://code.google.com/p/appdailysales/">http://code.google.com/p/appdailysales/</a>. Now since we have a <strong>Microsoft SSIS</strong> environment, I ported (part) of this code to C# so it can be run in a .NET environment. Note that you might have to <strong>change the bold parts</strong> to suit your needs.</p>
<p>Here&#8217;s the code:<span id="more-15"></span></p>
<blockquote><p>using System;<br />
using System.Collections;<br />
using System.Collections.Generic;<br />
using System.Collections.Specialized;<br />
using System.Text;<br />
using System.Text.RegularExpressions;<br />
using System.Net;</p>
<p>namespace ConsoleApplication1<br />
{<br />
class Program<br />
{<br />
static int daysToDownload = 1;<br />
static readonly String urlBase = &#8220;https://itts.apple.com&#8221;;<br />
static String fieldNameReportType = &#8220;&#8221;;<br />
static String fieldNameReportPeriod = &#8220;&#8221;;<br />
static String fieldNameDayOrWeekSelection = &#8220;&#8221;;<br />
static String fieldNameSubmitTypeName = &#8220;&#8221;;<br />
static String fieldNameDayOrWeekDropdown = &#8220;&#8221;;</p>
<p>static void Main(string[] args)<br />
{</p>
<p>Console.WriteLine(&#8220;fetching data&#8221;);</p>
<p>// First start up a session and get the sessionpage<br />
String SessionPage = GetSessionPage();</p>
<p>// After this navigate to the vendor page<br />
String VendorPage = GetVendorPage( SessionPage );</p>
<p>// After this get the ID for the dayOrWeekDropdwon<br />
String UrlDownload = GetDayOrWeekUrl(VendorPage);</p>
<p>DownloadFiles( UrlDownload );</p>
<p>Console.WriteLine(&#8220;done fetching data, press enter to continue&#8221;);<br />
Console.ReadLine();<br />
}</p>
<p>public static String GetSessionPage()<br />
{<br />
WebClient client = new WebClient();<br />
String data = client.DownloadString(urlBase + &#8220;/cgi-bin/WebObjects/Piano.woa&#8221;);</p>
<p>Match match = Regex.Match(data, &#8220;\&#8221; action=\&#8221;(.*)\&#8221;");</p>
<p>WebClient c2 = new WebClient();<br />
NameValueCollection myQueryStringCollection = new NameValueCollection();<br />
myQueryStringCollection.Add(&#8220;theAccountName&#8221;, &#8220;<strong>itunesaccountname</strong>&#8220;);<br />
myQueryStringCollection.Add(&#8220;theAccountPW&#8221;, &#8220;<strong>itunespassword</strong>&#8220;);<br />
myQueryStringCollection.Add(&#8220;1.Continue.x&#8221;, &#8220;0&#8243;);<br />
myQueryStringCollection.Add(&#8220;1.Continue.y&#8221;, &#8220;0&#8243;);<br />
c2.QueryString = myQueryStringCollection;</p>
<p>String downloadUrl = urlBase + match.Groups[1];<br />
Console.WriteLine(&#8220;Logging in on&#8221;);<br />
Console.WriteLine( downloadUrl );<br />
return c2.DownloadString( downloadUrl );<br />
}</p>
<p>public static String GetVendorPage( String SessionPage )<br />
{<br />
Match match = Regex.Match(SessionPage, &#8220;name=\&#8221;frmVendorPage\&#8221; action=\&#8221;(.*)\&#8221;");</p>
<p>String UrlDownload = urlBase + match.Groups[1];</p>
<p>MatchCollection matchCollection = Regex.Matches(SessionPage, &#8220;name=\&#8221;(.*?)\&#8221;");</p>
<p>fieldNameReportType = matchCollection[6].Groups[1].ToString();<br />
fieldNameReportPeriod = matchCollection[7].Groups[1].ToString();<br />
fieldNameDayOrWeekSelection = matchCollection[10].Groups[1].ToString();<br />
fieldNameSubmitTypeName = matchCollection[11].Groups[1].ToString();</p>
<p>WebClient client = new WebClient();<br />
NameValueCollection myQueryStringCollection = new NameValueCollection();<br />
myQueryStringCollection.Add(fieldNameReportType, &#8220;Summary&#8221;);<br />
myQueryStringCollection.Add(fieldNameReportPeriod, &#8220;Daily&#8221;);<br />
myQueryStringCollection.Add(fieldNameDayOrWeekSelection, &#8220;Daily&#8221;);<br />
myQueryStringCollection.Add(fieldNameSubmitTypeName, &#8220;ShowDropDown&#8221;);</p>
<p>client.QueryString = myQueryStringCollection;<br />
Console.WriteLine(&#8220;fetching vendor page on&#8221;);<br />
Console.WriteLine(UrlDownload);<br />
return client.DownloadString(UrlDownload);<br />
}</p>
<p>public static String GetDayOrWeekUrl(String VendorPage)<br />
{<br />
// Get the new session Url<br />
Match match = Regex.Match(VendorPage, &#8220;name=\&#8221;frmVendorPage\&#8221; action=\&#8221;(.*)\&#8221;");<br />
String UrlDownload = urlBase + match.Groups[1];</p>
<p>// Also fill in the DayOrWeek variable<br />
MatchCollection matchCollection = Regex.Matches(VendorPage, &#8220;name=\&#8221;(.*?)\&#8221;");<br />
fieldNameDayOrWeekDropdown = matchCollection[8].Groups[1].ToString();</p>
<p>Console.WriteLine(&#8220;fetching dayOrWeek variable: &#8221; + fieldNameDayOrWeekDropdown);</p>
<p>return UrlDownload;<br />
}</p>
<p>public static void DownloadFiles( String UrlDownload )<br />
{<br />
ArrayList reportDates = new ArrayList();<br />
for (int i = 1; i &lt;= daysToDownload; i++)<br />
{<br />
TimeSpan timespan = TimeSpan.FromDays(i);<br />
DateTime reportDate = DateTime.Today.Subtract(timespan);<br />
reportDates.Add(reportDate);<br />
}</p>
<p>foreach (DateTime date in reportDates)<br />
{<br />
WebClient client = new WebClient();<br />
NameValueCollection myQueryStringCollection = new NameValueCollection();<br />
myQueryStringCollection.Add(fieldNameReportType, &#8220;Summary&#8221;);<br />
myQueryStringCollection.Add(fieldNameReportPeriod, &#8220;Daily&#8221;);<br />
myQueryStringCollection.Add(fieldNameDayOrWeekDropdown, appleDate(date));<br />
myQueryStringCollection.Add(&#8220;download&#8221;, &#8220;Download&#8221;);<br />
myQueryStringCollection.Add(fieldNameDayOrWeekSelection, appleDate(date));<br />
myQueryStringCollection.Add(fieldNameSubmitTypeName, &#8220;Download&#8221;);<br />
client.QueryString = myQueryStringCollection;</p>
<p>String filename = &#8220;file.&#8221; + date.ToString(&#8220;dd_MM_yyyy&#8221;).Replace(&#8220;/&#8221;, &#8220;_&#8221;) + &#8220;.txt.gz&#8221;;<br />
Console.WriteLine(&#8220;fetching file: &#8221; + filename);<br />
client.DownloadFile(UrlDownload, &#8220;<strong>c:/&#8221; + filename </strong>);<br />
Console.WriteLine(&#8220;fetched file: &#8221; + filename + &#8221; &#8211; apple filename: &#8221; + client.ResponseHeaders.Get(&#8220;content-disposition&#8221;) );<br />
}<br />
}</p>
<p>public static String appleDate( DateTime date )<br />
{<br />
return System.Web.HttpUtility.UrlEncode( date.ToString(&#8220;MM/dd/yyyy&#8221;) );<br />
}<br />
}<br />
}</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://marc.blog.foreach.com/2010/07/itunes-connect-sales-report-script-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ojspc slow compilation and tags being recompiled</title>
		<link>http://marc.blog.foreach.com/2009/08/ojspc-slow-compilation-and-tags/</link>
		<comments>http://marc.blog.foreach.com/2009/08/ojspc-slow-compilation-and-tags/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 14:10:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://marc.blog.foreach.com/?p=5</guid>
		<description><![CDATA[So we use ojspc (Oracle Java Compiler) to compile our JSPs and tag libraries. This saves us the overhead when loading the sites that it needs to parse the JSPs and Tags and thus slows down the initial first hit on a page. We used to be able to compile an .ear in about 2 [...]]]></description>
			<content:encoded><![CDATA[<p>So we use ojspc (Oracle Java Compiler) to compile our JSPs and tag libraries. This saves us the overhead when loading the sites that it needs to parse the JSPs and Tags and thus slows down the initial first hit on a page.</p>
<p>We used to be able to compile an .ear in about 2 hours (which I think was long already). This project has about roughly 130 JSPs and quite some tag libraries. After a redesign of the site the compilation times started to increase, upto 4 hours, 8 hours, &#8230; This was making me nervous as it meant we had to stop our sprints sooner &#8230; to test sooner &#8230; to start building sooner. This is were my quest for the initial problem began.</p>
<p><strong>Why the hell does ojspc take so long to translate my JSPs??</strong></p>
<p>Roughly .. translating a JSP could take upto 2 minutes, with about 130 JSPs, well that easily takes you 2 hours. I started <strong>messing around with</strong> <strong>ojspc.jar</strong> seeing if I could call it natively from code, or if I could override a class and maybe play with the internals of ojspc. Not much success here. After monitoring the ojspc process, <strong>I saw it was spawning a javac process every once in a while</strong> &#8230; probably compiling stuff &#8211; right? If only I could have a peak there and see what exactly it was doing &#8230; and so I did.</p>
<p>I<strong> replaced the standard javac binary with a javac bash script</strong> which looked more or less like this:</p>
<p><span id="more-5"></span></p>
<blockquote><p>#!/bin/bash<br />
echo &#8220;===============================================================&#8221; &gt;&gt; /tmp/compile.log<br />
echo &#8220;$$ $PPID : $*&#8221; &gt;&gt; /tmp/compile.log</p></blockquote>
<p>This game me some interesting information on what ojspc  was trying to do, however the ojspc process died after trying to translate the first JSP. I assume it wasn&#8217;t finding the necessary classes to continue the compilation process.</p>
<p>So playing on with the workaround script &#8211; <strong>we included the original call the javac binary (now bjavac)</strong>:</p>
<blockquote><p>#!/bin/bash<br />
echo &#8220;===============================================================&#8221; &gt;&gt; /tmp/compile.log<br />
echo &#8220;$$ $PPID : $*&#8221; &gt;&gt; /tmp/compile.log<br />
jout=`/opt/app/oracle/product/as10g/jdk/bin/bjavac -J-Djavac.pipe.output=true $1 $2 $3 $4 $5 $6 $7 $8 2&gt;&gt;/tmp/compile.log`</p></blockquote>
<p>This actually compiled the necessary classes from the tag libs, and I noticed <strong>several tag libraries were coming back from time to time</strong>. For Example we have a &lt;main:header /&gt; tag which includes our common header. This comes back in each JSP. <strong>For every JSP this tag library was recompiled</strong>. Even worse &#8211; if you would have a tag library which formats numbers &lt;main:numberformatter /&gt; and used if several times within the same JSP, <strong>it would be recompiled for each occurence of the tag</strong>. Since we have custom tag libraries which implements HTML blocks on several parts of the site, the overhead was clear and <strong>something had to be done about keeping recompiling tag libraries over and over</strong>. The first attempt was the following script:</p>
<blockquote><p>#!/bin/bash<br />
echo &#8220;===============================================================&#8221; &gt;&gt; /tmp/compile.log<br />
echo &#8220;$$ $PPID : $*&#8221; &gt;&gt; /tmp/compile.log<br />
filename=`echo $4| cut -d&#8217;@&#8217; -f 2`<br />
javafile=`tail -1 $filename`<br />
filet=`echo $javafile| cut -d&#8217;.&#8217; -f 1`<br />
classfile=&#8221;$filet.class&#8221;<br />
ffname=`echo $classfile| awk -F/ &#8216;{print $NF}&#8217;`<br />
echo &#8220;Checking if $classfile exists&#8221; &gt;&gt; /tmp/compile.log<br />
if [ ! -s "$classfile" ]<br />
then<br />
echo &#8220;Must compile: $classfile&#8221;&gt;&gt;/tmp/compile.log<br />
jout=`/opt/app/oracle/product/as10g/jdk/bin/bjavac -J-Djavac.pipe.output=true $1 $2 $3 $4 $5 $6 $7 $8 2&gt;&gt;/tmp/compile.log`<br />
else<br />
echo &#8220;Skipping $classfile&#8221; &gt;&gt;/tmp/compile.log<br />
fi<br />
echo &#8220;Done, exit code: $?&#8221;&gt;&gt;/tmp/compile.log</p></blockquote>
<p>However Ojspc always <strong>terminated with a JspParseException</strong>. It didn&#8217;t like me skipping class files when it was necessary, pitty. After looking further through the Ojspc.jar files I noticed <strong>timestamps of the class files were important to please Ojspc</strong>, so we wrote another little script that fiddles with the timestamp of the .class file. The &#8220;else&#8221; branch in our above script became:</p>
<p>echo &#8220;Skipping $classfile&#8221; &gt;&gt;/tmp/compile.log<br />
java  FileUtil $classfile&gt;&gt;/tmp/compile.log</p>
<p>The java FileUtil program<strong> fiddled with the timestamps of the already generated .class file and added 10000 msecs to the lastmodified time</strong>. Hence ojspc was always happy. The FileUtil tool looked like this:</p>
<blockquote><p>import java.io.File;<br />
import java.util.Date;</p>
<p>public class FileUtil {</p>
<p>public void changeFiletime(String filename) {</p>
<p>File fileToChange = new File(filename);</p>
<p>//Check time of the file/directory<br />
Date filetime = new Date(fileToChange.lastModified());<br />
System.out.println(filetime.toString());</p>
<p>if (fileToChange.setLastModified(fileToChange.lastModified()+10000))<br />
System.out.println(&#8220;Successfile+10000!&#8221;);<br />
else<br />
System.out.println(&#8220;Failed!&#8221;);</p>
<p>//Check time again<br />
filetime = new Date(fileToChange.lastModified());<br />
System.out.println(filetime.toString());</p>
<p>}</p>
<p>public static void main(String[] args) {<br />
FileUtil fileutil = new FileUtil();<br />
fileutil.changeFiletime(args[0]);<br />
}<br />
}</p></blockquote>
<p><strong>Ojspc noticed the timestamp of the skipped .class file had changed and it was happy again</strong>, no more errors and the <strong>compilation times for our project dropped from 2 hours to 20 minutes</strong>. With all the documentation in hand and a workaround ready &#8230; it was time to open up a support request at Oracle Support. Following SR was created:</p>
<p>SR 7395808.994: OJSPC Batch translation keeps recompiling tag libraries was opened at Oracle Metalink.</p>
<p>Several weeks later a bug acknowledgement was released and after another while I received a temporary patch for ojspc.jar which works against <span class="nodatafound"><span>10.1.3.3.0. You can follow the bug process in following Bug report:<br />
</span></span></p>
<p><a href="https://metalink2.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=BUG&amp;p_id=8418503" target="_blank">BUG 8418503 &#8211; OJSPC COMPILES THE SAME TAG CLASSES REPEATEDLY WITHOUT REASON</a></p>
<p>The patched ojspc.jar skips the compilation of .class files which already have been compiled, with the overhead gone from my workaround scripts, <strong>compile times dropped further to 7 minutes</strong>.</p>
<p>We have been working with these Oracle compiled builds now for over several months and have not encountered any problems. If you need to try the temporary patch contact me.</p>
<p>The fix is expected to be released in the patch-set for 10.1.3.5.</p>
]]></content:encoded>
			<wfw:commentRss>http://marc.blog.foreach.com/2009/08/ojspc-slow-compilation-and-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OC4J blocked threads &#8230; part 2</title>
		<link>http://marc.blog.foreach.com/2009/02/oc4j-blocked-threads-part-2/</link>
		<comments>http://marc.blog.foreach.com/2009/02/oc4j-blocked-threads-part-2/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 20:50:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[blocked]]></category>
		<category><![CDATA[oas]]></category>
		<category><![CDATA[oc4j]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[rac]]></category>
		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://marc.blog.foreach.com/?p=4</guid>
		<description><![CDATA[And thus it became christmass and the new year 2009 was coming. When an upgrade was planned to the Oracle RAC so we could benefit from a new and faster storage. Quite some preparation work had been done by the developers and the database administrators to ensure a (temporary) replication could be setup between the [...]]]></description>
			<content:encoded><![CDATA[<p>And thus it became christmass and the new year 2009 was coming. When an upgrade was planned to the Oracle RAC so we could benefit from a new and faster storage.</p>
<p>Quite some preparation work had been done by the developers and the database administrators to ensure a (temporary) replication could be setup between the old RAC and the new RAC, so all data would be transferred more or less &#8220;automatically&#8221; into the new RAC.</p>
<p>And then the big day came. We stopped the OC4J containers, we changed the datasources while the database administrators synced the RACs a last time and when ready we started the OC4J containers back to run on the new RAC.</p>
<p><span style="font-size: 130%;">Uh-oh&#8230;blocked threads</span></p>
<p>We were happy the upgrade went smooth and the websites were running more crispier than ever until &#8230; the containers started to lock up for some non-apparent reason. Nothing we hadn&#8217;t done before, so I took a thread dump of the OC4J to see what was going on.<br />
<span id="more-4"></span>Thread t@788: (state = BLOCKED)</p>
<blockquote><p>- oracle.jdbc.pool.OracleImplicitConnectionCache.retrieveCacheConnection(java.lang.String, java.lang.String, java.util.Properties) @bci=0, line=651 (Compiled frame; information may be imprecise)<br />
- oracle.jdbc.pool.OracleImplicitConnectionCache.getCacheConnection(java.lang.String, java.lang.String, java.util.Properties) @bci=4, line=549 (Compiled frame)<br />
- oracle.jdbc.pool.OracleImplicitConnectionCache.getConnection(java.lang.String, java.lang.String, java.util.Properties) @bci=65, line=430 (Interpreted frame)<br />
- oracle.jdbc.pool.OracleDataSource.getConnection(java.lang.String, java.lang.String, java.util.Properties) @bci=31, line=432 (Interpreted frame)<br />
- oracle.jdbc.pool.OracleDataSource.getConnection(java.lang.String, java.lang.String) @bci=16, line=203 (Interpreted frame)<br />
- oracle.jdbc.pool.OracleDataSource.getConnection() @bci=33, line=179 (Compiled frame)</p></blockquote>
<p>This thread was actually deadlocked by</p>
<blockquote><p>Thread t@29: (state = BLOCKED)<br />
- oracle.jdbc.driver.PhysicalConnection.closeLogicalConnection() @bci=0, line=1581 (Compiled frame; information may be imprecise)<br />
- oracle.jdbc.driver.LogicalConnection.cleanupAndClose(boolean) @bci=31, line=267 (Interpreted frame)<br />
- oracle.jdbc.pool.OracleImplicitConnectionCache.closeCheckedOutConnection(oracle.jdbc.pool.OraclePooledConnection, boolean) @bci=45, line=1503 (Interpreted frame)<br />
- oracle.jdbc.pool.OracleImplicitConnectionCacheThread.runAbandonedTimeout(long) @bci=155, line=258 (Interpreted frame)<br />
- oracle.jdbc.pool.OracleImplicitConnectionCacheThread.run() @bci=93, line=81 (Interpreted frame)</p></blockquote>
<p>Also we were seeing a lot of connections to the OC4J TCP port which were on TIME_WAIT.</p>
<blockquote><p>netstat -an | grep 12501 | wc -l<br />
&#8212;&gt;  444</p></blockquote>
<p>A ticket was opened at Oracle in which we explained the situation. The first deadlock was caused by the <span style="font-weight: bold;">abandoned-connection-timeout</span> property which we had put to 60. Oracle advised us to remove the entry or put it on -1. We had this in our datasource just for security reason, if ever a query took more than 60 seconds we would break it off rather than keep it running for possibly much longer.</p>
<p>I found it a strange solution since we had not changed anything to the application level, never did we upgrade JDBC drivers or anything else &#8230; but ok &#8230; after setting the abandoned-connection-timeout property to -1 or just removing it, we started getting another behaviour. Now we would get Connection Timeout exceptions from the JDBC driver &#8230; well &#8230; kinda logica if you don&#8217;t kill anything anymore, I guess the pool got used up for some reason. The stacktrace would look somewhat like this</p>
<blockquote><p>08/12/23 03:32:26 java.sql.SQLException: Io exception: Io exception: Connection timed out<br />
08/12/23 03:32:26       at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:77)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:132)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:200)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:264)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:575)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.ClobAccessor.getString(ClobAccessor.java:296)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.T4CClobAccessor.getString(T4CClobAccessor.java:77)<br />
08/12/23 03:32:26       at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:2138)</p></blockquote>
<p>Ok we do heavily use Clobs, as sometimes was not adviced by some people who also run sister-sites. But avoiding a <span style="font-weight: bold;">feature</span> in Oracle because you know <span style="font-style: italic;">it might</span> give you problems &#8211; we thought that was too far fetched. We saw this exception when using one of the latest JDBC-drivers available. As Oracle told us to &#8220;try this one out&#8221;.</p>
<p>Meanwhile we started writing restart scripts, using a bit of python, when the socket would not answer after a decent period of time, we&#8217;d issue an OC4J restart so at least we could serve client request more or less decently. And since christmas and new year was coming closer, everything went just a tad slower.</p>
<p>What followed was a whole list of snoops and database traces. If you care to follow this SR just let me know your email-address as a comment. Meanwhile I wrote a wrapper for our DAO and noticed that queries that were using CLOBs were sometimes not finishing. This means that some of those queries stayed &#8220;running&#8221; and thus eventually we ran out of connections in the connection pool.</p>
<p>We were told to fiddle around with the sqlnet.expire_time. After experimenting a bit we found out that this value was set to 10 minutes. Setting the sqlnet.expire_time to 4 minutes helped us quite a bit, as it took much longer for JDBC to fill all te connections in the connection pool. At least our website was more stable (and needing less restarts).</p>
<p>Quite some days related we encountered the following snoop (IP addresses obfuscated)</p>
<blockquote><p>61035 173.904541111.11.111.11222.22.22.222 TCP ingreslock &gt; 46083 [PSH, ACK] Seq=115508 Ack=30515 Win=49680 [TCP CHECKSUM INCORRECT] Len=911<br />
61073 174.318971111.11.111.11222.22.22.222 TCP [TCP Retransmission] ingreslock &gt; 46083 [PSH, ACK] Seq=115508 Ack=30515 Win=49680 [TCP CHECKSUM INCORRECT] Len=911<br />
61274 175.158981111.11.111.11222.22.22.222 TCP [TCP Retransmission] ingreslock &gt; 46083 [PSH, ACK] Seq=115508 Ack=30515 Win=49680 [TCP CHECKSUM INCORRECT] Len=911<br />
61998 176.839470111.11.111.11222.22.22.222 TCP [TCP Retransmission] ingreslock &gt; 46083 [PSH, ACK] Seq=115508 Ack=30515 Win=49680 [TCP CHECKSUM INCORRECT] Len=911<br />
63332 180.198899111.11.111.11222.22.22.222 TCP [TCP Retransmission] ingreslock &gt; 46083 [<span id="SPELLING_ERROR_0" class="blsp-spelling-error">PSH</span>, <span id="SPELLING_ERROR_1" class="blsp-spelling-error">ACK</span>] Seq=115508 <span id="SPELLING_ERROR_2" class="blsp-spelling-error">Ack</span>=30515 Win=49680 [<span id="SPELLING_ERROR_3" class="blsp-spelling-error">TCP</span> <span id="SPELLING_ERROR_4" class="blsp-spelling-error">CHECKSUM</span> INCORRECT] Len=911</p></blockquote>
<p>This was said to be a retransmission problem by Oracle. Liking this explanation more we opened a ticket at Sun to see if they had noticed any issues like this. Sun coordinated with Oracle to look at the snoops and proposed us the following kernel parameter:</p>
<blockquote><p>set <span id="SPELLING_ERROR_5" class="blsp-spelling-error">ip</span>:<span id="SPELLING_ERROR_6" class="blsp-spelling-error">dohwcksum</span>=0</p></blockquote>
<p>And with this kernel parameter &#8230; all problems went away. Now I really am not a Solaris expert to know what this kernel parameter does. I read it&#8217;s a hardware <span id="SPELLING_ERROR_7" class="blsp-spelling-error">checksum</span>. I personally think it&#8217;s weird to remove a &#8220;check&#8221; which is supposed to say if things are correct or not &#8230; but hey &#8230; Sun and Oracle told us to do it, and the problems are gone.</p>
<p>And after 3 months the end of this SR reached a Soft Close state and our website ran smoothly again. Never think a database upgrade might not impact your site obviously.</p>
]]></content:encoded>
			<wfw:commentRss>http://marc.blog.foreach.com/2009/02/oc4j-blocked-threads-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OC4J Blocked threads</title>
		<link>http://marc.blog.foreach.com/2008/03/oc4j-blocked-threads/</link>
		<comments>http://marc.blog.foreach.com/2008/03/oc4j-blocked-threads/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 19:21:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[oas]]></category>
		<category><![CDATA[oc4j]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://marc.blog.foreach.com/?p=3</guid>
		<description><![CDATA[Infrastructure Setup It all started back in November 2007 when I was asked by my colleagues at Foreach if I could come and help out to do a performance review. The site in question was the site of De Tijd (or L&#8217;Echo in french) which was being ported from Microsoft SQL Server and ASP to [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-size:130%;">Infrastructure Setup</span></p>
<p>It all started back in November 2007 when I was asked by my colleagues at <a href="http://www.foreach.com/">Foreach</a> if I could come and help out to do a performance review. The site in question was the site of <a href="http://www.tijd.be/">De Tijd</a> (or <a href="http://www.lecho.be/">L&#8217;Echo</a> in french) which was being ported from Microsoft SQL Server and ASP to a mix of Oracle Database (for articles) and Microsoft SQL Server 2005 (for quotations). The frontend would be handled by Oracle Application Servers (OAS) &#8211; with the usual Oracle Containers for Java (OC4J &#8211; version 10.1.3.3.0) and Apache servers above. In front of that there&#8217;s the usual setup of load balancers and Oracle WebCache servers.</p>
<p><span style="font-size:130%;">Performance review</span></p>
<p>Of course you start by the usual performance bottlenecks. Check primary keys, integrities, add unobstrusive logging to the DAO objects (log4j), start caching relevant objects with reasonable expire times (ehcache) &#8230; do more stress tests, and so on &#8230; Performance was reasonably satisfactory for launch and then that day finally came. The site was launched.</p>
<p><span style="font-size:130%;">Blocked threads</span></p>
<p>It wasn&#8217;t before long until we started seeing strange behaviours on the origin servers (the servers behind the webcaches). At random times they would just lock-up, needing a restart of the OC4J container about every day. After doing a thread dump we would notice several blocked threads like these:</p>
<p><span id="more-3"></span></p>
<blockquote><p>frame: 0: com.evermind.server.http.HttpSite.getApplication(HttpSite.java:418)<br />
frame: 1: com.evermind.server.http.AJPRequestHandler.initAJP(AJPRequestHandler.java:1011)<br />
frame: 2: com.evermind.server.http.AJPRequestHandler.initRequest(AJPRequestHandler.java:615)<br />
frame: 3: com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:243)<br />
frame: 4: com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:187)<br />
frame: 5: oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)<br />
frame: 6: com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)<br />
frame: 7: java.lang.Thread.run(Thread.java:595)</p></blockquote>
<p>Most of them were also pointing to the URLs of the detail of an article. After finding no relevant bottlenecks in our application. We did notice a lot of <span style="font-weight: bold;">BLOCKED threads</span> when we did a stress on the article page. If only I could look at <span style="font-weight: bold;">HttpSite.getApplication().</span> I tried finding the source code for Orion, but of course that failed. So I reverted to look at the bytecode from <span style="font-weight: bold;">oc4j-internal.jar</span> *coughs*.</p>
<p>Once you head over there you will see that this method looks for a <span style="font-weight: bold;">contextCache </span>which is based on the path. The path is actually just the name of the URI in this case (without the querystring). You will also notice there&#8217;s a <span style="font-weight: bold;">JVM lock</span> there &#8211; when the path is not found, creating a new entry in the contextCache. So euhm wait &#8230; we have pretty URLs &#8230; does that mean we are <span style="font-weight: bold;">&#8220;poluting&#8221; the contextCache with entries</span> to our pretty URLs and locking the whole thing down for no reason ?<br />
Seems like it was &#8230; we needed a quick fix so we changed the<span style="font-weight: bold;"> backend to work with non-pretty</span> URLs and used a ProxyPass to put the logic of turning pretty URLs in non-pretty URLs.</p>
<p>This means you end up with 2 virtual hosts. One that does the frontend serving with pretty URLs and ProxyPasses to &#8230; the same machine (other vhost) with non-pretty URLs.</p>
<p><span style="font-size:130%;">Result</span></p>
<p><span style="font-weight: bold;">No more blocked threads</span>. contextCache size was kept to a minimum. Apache handles the ProxyPasses quite well. Stable running sites since then.<br />
Are there drawbacks ? Yes:</p>
<ul>
<li>You are doing things more than once by ProxyPassing</li>
<li>You loose your pretty URLs and need to rebuild them when generating page &#8230; but hey that can be done pretty quick performance wise</li>
<li>You have to be careful how you configure your applications and mount points.</li>
<li>You have to be careful how you redirect &#8230; You don&#8217;t want to redirect to a non-pretty URL (which might only resolve internally anyway).</li>
</ul>
<p>So seems like having your <span style="font-weight: bold;">pretty URLs handled by OC4J was not a good idea</span>. I  can&#8217;t keep but wonder if Tomcat would have had any issue with this&#8230;</p>
<p><span style="font-size:130%;"><span style="font-size:100%;"><span style="font-size:130%;"><span style="font-size:100%;"><span style="font-size:130%;"></span></span></span></span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://marc.blog.foreach.com/2008/03/oc4j-blocked-threads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

