tag:blogger.com,1999:blog-243845442024-02-21T05:30:19.589+11:00Development Answers (No Questions)Solutions to the problems encountered by a Java Developer. No Questions! Just Answers.Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.comBlogger79125tag:blogger.com,1999:blog-24384544.post-60662470281623265512018-07-11T11:45:00.001+10:002018-07-11T12:00:42.323+10:00Perform an Auto-Submit Form Post from an Angular page<span class="daKeywords">Keywords:</span><br />
angular angular2 form post auto submit <br />
<br />
<span class="daProblem">Problem:</span><br />
You need to send the user to another application (in the current view or new window) via a form-post that includes a payload of inputs. <br />
<br />
How do you:<ol type="a"><li>avoid the form being handled by the angular framework; <i>and</i> (for bonus points) </li>
<li>make the form dynamically auto-submit (to avoid the user having to hit a submit button)? </li>
</ol><br />
<span class="daSolution">Solution:</span><br />
For (a) the key to ensuring the <code>form</code> element in the template is not handled by the angular framework - and therefore allowing it to submit to the defined <code>action</code> is adding the <b><code>ngNoForm</code></b> attribute. There's notes in a discussion <a href="https://stackoverflow.com/questions/34835516/how-to-submit-form-to-server-in-angular2">How to submit form to server in Angular2</a> ... at the time of writing, it <a href="https://github.com/angular/angular/issues/19497">doesn't appear to be well documented</a>. <br />
<br />
<pre class="brush:html;highlight: [1]"><form ngNoForm
#myFormPost name="myFormPost"
action="https://httpbin.org/post"
method="POST"
target="_blank" >
...
</form>
</pre><br />
For (b) the dynamic auto-submit, you can obtain the reference to the form and submit it from the component code:<br />
<pre class="brush:js">@ViewChild('myFormPost') myFormPost: ElementRef;
...
// in some place where the form has been set
this.myFormPost.nativeElement.submit();
</pre><br />
A full working example is here: <a href="https://stackblitz.com/edit/angular-form-post-auto-submit?file=src/app/app.component.html">angular-form-post-auto-submit (on StackBlitz)</a><br />
(this includes demo handling of hidden multi-line inputs)<br />
<br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-75541437301344523432016-02-23T08:15:00.002+11:002016-04-26T21:20:54.004+10:00HSQLDB ignores column aliases in select statement by default<span class="daKeywords">Keywords:</span><br />
HSQL HSQLDB column alias ignored NullPointerException JSTL <br />
<br />
<span class="daProblem">Problem:</span> <br />
I can't pin point where this change happened from the HSQLDB changelogs but somewhere between HSQL 1.8.0.7 and 2.2.5, the handling of column aliases has changed. This is particularly problematic if attempting to lookup via alias name in JSTL where failed lookup of results (due to wrong column names) come back as null. <br />
<br />
This is a standalone JSP example:<br />
<pre class="brush:xml; highlight: [22,23]"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<sql:setDataSource var="dataSource"
url="jdbc:hsqldb:mem:example/aliasprob"
driver="org.hsqldb.jdbcDriver"/>
<sql:update dataSource="${dataSource}">
create table if not exists USERS (
fullname varchar(255),
telephone varchar(255)
);
</sql:update>
<sql:update dataSource="${dataSource}">
insert into USERS (fullname, telephone)
values ('Joe Bloggs', '123-5555');
</sql:update>
<sql:update dataSource="${dataSource}">
insert into USERS (fullname, telephone)
values ('Fred Twitters', '456-5555');
</sql:update>
<sql:query var="users" dataSource="${dataSource}">
select fullname as "name"
, telephone as "phone"
from USERS
</sql:query>
<!DOCTYPE html>
<html>
<head>
<title>Alias Problems</title>
</head>
<body>
<p>These are the users:</p>
<table border="1">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<c:forEach var="row" items="${users.rows}">
<tr>
<td>${row['name']}</td>
<td>${row['phone']}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
<sql:update dataSource="${dataSource}">
drop table USERS;
</sql:update>
</pre><br />
With the above test, you get two rows in the result table with empty cells for the values. If the code above was changed to <i>ignore</i> the aliases used in the 'AS' statements and use the underlying column names the data would be visible. If I have code that uses column aliases in this way does the select statement have to be changed to work with HSQLDB?<br />
<br />
<span class="daSolution">Solution:</span> <br />
HSQLDB introduced the <a href="http://hsqldb.org/doc/guide/dbproperties-chapt.html#N15101"><code>get_column_name</code></a> property which "returns the underlying column name" (despite an alias being used) and is <code>true</code> by default. The documentation also states this is for "compatibility with other JDBC driver implementations". I suspect there's some inconsistency with with way the JSTL SQL tags are using <code>ResultSet.getColumnLabel(int)</code> vs <code>ResultSet.getColumnName(int)</code>. <br />
<br />
When using JSTL, there's no distinction between column labels or names when using the <code>row['column']</code> syntax so using <code>get_column_name=false</code> in the HSQL connection URL is a quick fix - making the JSTL behaviour at least, consistent with other JDBC drivers. <br />
<br />
In the example code above, this would look like:<br />
<pre class="brush:xml; highlight: [2]"><sql:setDataSource var="dataSource"
url="jdbc:hsqldb:mem:example/aliasprob;get_column_name=false"
driver="org.hsqldb.jdbcDriver"/>
</pre>Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-78975094366156098962015-10-30T18:00:00.000+11:002015-11-02T13:43:00.646+11:00Database schema naming for Vendor Neutrality <span class="daKeywords">Keywords:</span><br />
database vendor-agnostic identifier limitations Oracle SQL Server PostgreSQL HSQL MySQL table column <br />
<br />
<span class="daProblem">Problem:</span><br />
It's surprisingly not a common topic of dicussion, but if you want to author database scripts in a way that is vendor-agnostic the consensus seems to be to conform to ANSI SQL. Are there any guides for how to name the schema identifiers to comply with the various vendor's (character limit) limitations?<br />
<br />
<span class="daSolution">Solution:</span><br />
I couldn't find a good cross-vendor summary, so here's an attempt at looking at the important identifier limitations across some vendors.<br />
<br />
<table border="1"> <thead>
<tr>
<th rowspan="2">Vendor </th>
<th colspan="3">Identifier Limit (characters)</th>
<th rowspan="2">Notes </th>
</tr>
<tr>
<th>TABLE </th>
<th>COLUMN </th>
<th>CONSTRAINT </th>
</tr>
</thead>
<tbody>
<tr>
<td>Oracle </td>
<td>30 </td>
<td>30 </td>
<td>30 </td>
<td><br />
<a href="https://docs.oracle.com/database/121/SQLRF/sql_elements008.htm#SQLRF51129">https://docs.oracle.com/database/121/SQLRF/sql_elements008.htm#SQLRF51129</a><br />
</td>
</tr>
<tr>
<td>PostgreSQL </td>
<td>63 </td>
<td>63 </td>
<td>63 </td>
<td><br />
<a href="http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS</a><br />
</td>
</tr>
<tr>
<td>MS SQL Server </td>
<td>128 </td>
<td>128 </td>
<td>128 </td>
<td><br />
<a href="https://msdn.microsoft.com/en-us/library/ms175874.aspx">https://msdn.microsoft.com/en-us/library/ms175874.aspx</a><br />
</td>
</tr>
<tr>
<td>MySQL </td>
<td>64 </td>
<td>64 </td>
<td>64 </td>
<td><br />
<a href="https://dev.mysql.com/doc/refman/5.0/en/identifiers.html">https://dev.mysql.com/doc/refman/5.0/en/identifiers.html</a><br />
</td>
</tr>
<tr>
<td>HSQL </td>
<td>128 </td>
<td>128 </td>
<td>128 </td>
<td><br />
<a href="http://hsqldb.org/doc/2.0/guide/databaseobjects-chapt.html#dbc_table_creation">http://hsqldb.org/doc/2.0/guide/databaseobjects-chapt.html#dbc_table_creation</a><br />
</td>
</tr>
<tr>
<td>DB2 </td>
<td>30 <sup>*</sup></td>
<td>30 <sup>*</sup></td>
<td>18 <sup>*</sup></td>
<td><br />
<sup>*</sup>Limit increased to 128 from v9.5<br/><br />
<a href="https://www-01.ibm.com/support/knowledgecenter/SSEPGG_9.5.0/com.ibm.db2.luw.wn.doc/doc/c0051391.html">https://www-01.ibm.com/support/knowledgecenter/SSEPGG_9.5.0/com.ibm.db2.luw.wn.doc/doc/c0051391.html</a><br />
</td>
</tr>
</tbody>
</table><br />
If you are concerned with complying with all the above vendors, then the lowest common denominator here is Oracle at 30 characters for table/column & constraints. <br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-7829165203100411752014-11-28T16:03:00.001+11:002014-11-28T16:03:28.139+11:00Avoid using java.io.File.lastModified() for sorting Files<span class="daKeywords">Keywords:</span> <br />
java File lastModified timestamp ext3 ext4 linux windows sort order milliseconds<br />
<br />
<span class="daProblem">Problem:</span> <br />
It seems like a basic use-case - order a list of files based on the order they were modified. <code><a href="http://docs.oracle.com/javase/7/docs/api/java/io/File.html#lastModified()">File.lastModified()</a></code> seems a reasonable choice for basing a <code><a href="http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html">Comparator</a></code> on, based on the documentation:<br />
<blockquote>A long value representing the time the file was last modified, measured in <i>milliseconds</i> since the epoch ...</blockquote><br />
So, assuming the files are not made any quicker than 1-per millisecond this should work fine right? <b>No.</b> For some reason, on linux based systems <code>File.lastModified()</code> is <i>always rounded to the second</i>. This appears to be a (legacy) limitation with 'ext3' (and earlier?) file-systems that persists to this day - even if the file-system is ext4 (with nanosecond precision). On a windows based system (with NTFS, 100ns precision) the <code>File.lastModified()</code> values are to the millisecond (I'm not the first person to notice the difference - <a href="http://www.coderanch.com/t/384700/java/java/File-lastModified-windows-linux"><code>File.lastModified()</code> on windows vs linux</a>). <br />
<br />
Problems with sorting files on linux don't seem to be isolated to java "<a href="http://stackoverflow.com/questions/3814290/order-files-by-creation-time-to-the-millisecond-in-bash">Order files by creation time to the millisecond in Bash</a>" - though I suspect that thread is actually based on using an ext3 file-system, as on an ext4 file-system you can get this working with <code>ls -latr --full-time</code>.<br />
<br />
<i>Q: </i>How do you know what type of file-system you're running? <br />
<i>A: </i><code><a href="http://www.cyberciti.biz/faq/linux-how-to-determine-find-out-file-system-type/">df -T</a></code> <br />
<br />
<i>Q: </i>What precision will the file-system support? <br />
<i>A: </i>See <a href="http://en.wikipedia.org/wiki/Comparison_of_file_systems#Metadata">Comparison of file systems</a> article and the 'Max Timestamp Resolution' column. <br />
<br />
<i>Q: </i>If I'm still unsure, is there a test case I can try?<br />
<i>A: </i>Here's a basic one:<br />
<pre class="brush:java;">import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileModified {
public static void main(String[] args) throws IOException {
File file = File.createTempFile("timestamp-test-", ".txt");
FileWriter writer = new FileWriter(file);
writer.append("updated");
writer.close();
System.out.println("via " + file.getClass().getName()
+ "\n\t" + file.getAbsolutePath() + "\n\t\tmodified: " + file.lastModified() + "ms");
}
}
</pre><br />
If you establish that the target environment(s) for your java application are on file-systems that do support a higher than <i>1 second</i> precision how do you get access to this from java?<br />
<br />
<br />
<span class="daSolution">Solution:</span> <br />
The closest bug report I can find is <a href="http://bugs.java.com/view_bug.do?bug_id=6939260">JDK-6939260</a>. But it appears that the bug title has been changed to propose exposing higher than millisecond precision for files - the side note made in the comments states "it's not possible to support this with java.io.File because it specifies that the last modified time is returned in milliseconds". This missed the point in the original bug description stating "The end of the number is always 000" - ie parking micro/nano second precision, shouldn't the method provide at least millisecond precision if the underlying filesystem supports this (or higher)?<br />
<br />
It appears for new features (and bug fixes?) related to the capabilites of the file-system, this functionality is going to be implemented in <a href="http://docs.oracle.com/javase/8/docs/api/java/nio/file/package-summary.html">java.nio.file</a>. So if you're using java 1.8+ you <i>may</i> be able access more accurate timestamps via <code><a href="http://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#getLastModifiedTime(java.nio.file.Path,%20java.nio.file.LinkOption...)">Files.getLastModifiedTime(Path,...)</a></code>. The updated test case becomes:<br />
<pre class="brush:java;">import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.concurrent.TimeUnit;
public class FileModified {
public static void main(String[] args) throws IOException {
File file = File.createTempFile("timestamp-test-", ".txt");
FileWriter writer = new FileWriter(file);
writer.append("updated");
writer.close();
System.out.println("via " + file.getClass().getName()
+ "\n\t" + file.getAbsolutePath() + "\n\t\tmodified: " + file.lastModified() + "ms");
Path filePath = FileSystems.getDefault().getPath(file.getAbsolutePath());
FileTime modified = Files.getLastModifiedTime(filePath);
System.out.println("via " + modified.getClass().getName() + "\n\t" + filePath
+ "\n\t\tmodified: " + modified.toMillis() + "ms (" + modified.to(TimeUnit.NANOSECONDS) + "ns)");
}
}
</pre><br />
Note that although <code>java.nio.file.attribute.FileTime</code> exists in java 1.7, <a href="http://bugs.java.com/view_bug.do?bug_id=6939260">JDK-6939260</a> claims that it's only going to be fixed in 8 onwards (I can't tell which update - I tried the latest available and it still fails). <br />
<br />
If you need to support java 1.7 or below on linux there is no staightforward option (short of parsing <code>ls --full-time</code> command output). If your system is in control of the files being written, my suggestion would be to maintain a separate record of creation/modified time - assuming order by time is important and you need higher than per-second precision. <br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-45439064671139263462014-06-20T17:10:00.000+10:002014-06-20T17:12:15.829+10:00Using JCR-SQL2 for querying ACLs in a Jackrabbit repository<span class="daKeywords">Keywords:</span><br />
jcr-sql2 query jackrabbit ACL ACE access controls nt:hierarchyNode rep:policy<br />
<br />
<span class="daProblem">Problem:</span><br />
The ultimate problem was actually how do you handle 'gracefully' removing Principals from the (default) jackrabbit security workspace when there's the potential they are being referenced by either: (a) groups; or (b) access controls (ACLs). This may be a topic for another (much more detailed) post, but for now the focus is on (b) detecting if there are any ACLs in the repository that reference the Principal. <br />
<br />
Aside: why is it a concern? Removing the Principal won't effect enforcement of the access controls, but anything attempting to process the ACL definition will hit an error for the missing Principal:<pre>javax.jcr.InvalidItemStateException: Item does not exist anymore: 6e332039-2956-323c-8e82-212de8f88ff0`</pre><br />
The <a href="http://wiki.apache.org/jackrabbit/AccessControl">AccesControl</a> documentation on the jackrabbit wiki states:<br />
<blockquote><b>How Resource-based ACLs are stored</b><br />
Resource-based ACLs are stored per resource/node in a special child node <code>rep:policy</code>. This one will have a list of <code>rep:GrantACE</code> child nodes (usually named <code>allow</code>, <code>allow0</code>,...) for grant access control entries and <code>rep:DenyACE</code> child nodes (usually named <code>deny</code>, <code>deny0</code>,...) for deny access control entries.<br />
<br />
Each ACE node has a <code>rep:principalName</code> STRING property pointing to the user or group this ACE belongs to, and a <code>rep:privileges</code> NAME multi-value property, containing all the privileges of this ACE.<br />
<br />
Note that you can read/browse these nodes using the JCR API, but cannot modify them. This must always happen through the JCR access control API.<br />
</blockquote><br />
How do you target these <code>rep:policy</code> items in a JCR-SQL2 query ... and more importantly has anyone done this before - to save me the time?<br />
<br />
<br />
<span class="daSolution">Solution:</span><br />
I couldn't find an example, but by careful reading of the <code>builtin_nodetypes.cnd</code> (and some trial and error) the following query will list all access control entities (ACEs) that reference a given Principal (i.e a User or Group) with-in a given access control list (ACL) set on a resource (file or folder).<pre class="brush:sql">select resource.*, ace.*
from [nt:hierarchyNode] as resource
inner join [rep:ACL] as acl
ON ISCHILDNODE(acl, resource)
inner join [rep:ACE] as ace
ON ISCHILDNODE(ace, acl)
where ace.[rep:principalName] = "kevin"
</pre><br />
The results will look like (in table form):<br />
<table border="1"><thead>
<tr> <td><i>Result Node-path</i></td><td>resource.jcr:createdBy</td><td>resource.jcr:created</td><td>resource.jcr:primaryType</td><td>ace.rep:glob</td><td>ace.rep:nodePath</td><td>ace.rep:principalName</td><td>ace.jcr:primaryType</td> </tr>
</thead> <tbody>
<tr> <td>/files/example</td><td>jack-admin</td><td>2014-05-06T07:08:09.100+11:00</td><td>nt:folder</td><td></td><td></td><td>kevin</td><td>rep:GrantACE</td> </tr>
</tbody> </table><br />
Note that 'Result Node-path' - full path to the resource - won't (and can't) be a a "column" Value in the result <code>javax.jcr.query.Row</code> items but can be obtained via a <code>javax.jcr.Node</code> item referenced by the <code>javax.jcr.query.Row</code>. Also note that the Principal reference here is via the 'name' as stored in the protected <code>rep:principalName</code> field - even if using the default security workspace, this <i>won't</i> be the full 'principal path' (path to the org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal). <br />
<br />
<span class="daNotes">Notes:</span> <br />
The <a href="http://stackoverflow.com/tags/jcr-sql2/info">stackoverflow <b>[jcr-sql2]</b> info page</a> includes a pretty neat summary of what JCR-SQL2 is with links to the reference specs and implementations (note the above is specific to jackrabbit). The <a href="http://www.h2database.com/jcr/grammar.html">JCR 2.0 SQL-2 Grammar</a> diagrams are particularly useful. <br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-29223613341561868972013-10-31T20:30:00.000+11:002013-11-01T16:08:24.856+11:00Quick Start to tracing JDBC SQL operations using log4jdbc<span class="daKeywords">Keywords:</span><br />
database logging show SQL log4jdbc tomcat JNDI log4j trace performance timing<br />
<br />
<span class="daProblem">Problem:</span><br />
Given a complex web application (with many moving parts), there's performance issues that first impressions seem to point at environment-specific database latency. Is there any way to trace/profile/monitor <i>all</i> the SQL statements being made to the database (preferably with timings)? <br />
<br />
<span class="daSolution">Solution:</span><br />
<a href="https://code.google.com/p/log4jdbc/">log4jdbc</a> seamlessly lets you configure a logger between your application and the JDBC connection. Documentation on the log4jdbc site is very good and has just about all you need to know, below is a "quick start" for the impatient.<br />
<br />
<h2>Step 1: Jar File(s)</h2>Drop the <b><code>log4jdbc4-[version].jar</code></b> file into <code>[webapp]/WEB-INF/lib</code>. <br />
You'll also need:<ul><li>a supported logging framework (log4j: <code>log4j-[version].jar</code>)</li>
<li>the SLF4J API (<code>slf4j-api-[version].jar</code> - already had it)</li>
<li>the SLF4J jar to use this logging framework (<code>slf4j-log4j12-[version].jar</code> - already had it)</li>
</ul><br />
<h2>Step 2: Driver Class and URL</h2><ol type="a"><li>Change the database resource definition to use the driver class <b><code>net.sf.log4jdbc.DriverSpy</code></b> ('spy' as it will work out the correct 'real' driver class to use).<br />
<li>Simply <i>prepend</i> <b><code>jdbc:log4</code></b> to the existing URL.</li><br />
</ol>
For a PostgreSQL database connection configured as a JNDI/JDBC Resource in Tomcat, this will look like:<pre class="brush:xml;highlight:[5,6]"> <Resource
name="jdbc/example"
type="javax.sql.DataSource"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
driverClassName="net.sf.log4jdbc.DriverSpy"
url="jdbc:log4jdbc:postgresql://localhost:5432/example"
username="postgres" password="***"
maxActive="20" maxIdle="10" maxWait="-1"
removeAbandoned="true" removeAbandonedTimeout="120" logAbandoned="true"
auth="Container"
charset="UTF-8" />
</pre>
<h2>Step 3: Logging Config</h2>There's detailed notes on the five key loggers and an example <a href="https://code.google.com/p/log4jdbc/source/browse/doc/log4j.properties"><code>log4j.properties</code></a> is available. But if you just want to see SQL + timings, the following will log this all to console:<pre class="brush:plain;highlight:[10]">log4j.logger.jdbc.audit=FATAL,Log4JDBC
log4j.additivity.jdbc.audit=false
log4j.logger.jdbc.resultset=FATAL,Log4JDBC
log4j.additivity.jdbc.resultset=false
log4j.logger.jdbc.sqlonly=FATAL,Log4JDBC
log4j.additivity.jdbc.sqlonly=false
log4j.logger.jdbc.sqltiming=INFO,Log4JDBC
log4j.additivity.jdbc.sqltiming=false
log4j.logger.jdbc.connection=FATAL,Log4JDBC
log4j.additivity.jdbc.connection=false
log4j.appender.Log4JDBC=org.apache.log4j.ConsoleAppender
log4j.appender.Log4JDBC.layout=org.apache.log4j.PatternLayout
log4j.appender.Log4JDBC.layout.ConversionPattern=%-5p [%d{DATE} %c]: %m%n
</pre>
<br/>
<br/>
That's it. Start up the application and it should function exactly as it did before, but <i>all</i> SQL operations (made via the JNDI connection pool resource in my example) will be logged in the form:<pre>INFO [01 Nov 2013 12:00:00,000 jdbc.sqltiming]: SELECT NAME FROM PERSON WHERE ID=54321
{executed in 1 msec}
</pre>
<br/>
<br/>
<span class="daNotes">Notes:</span>
<h2>Bonus Step: Trace back to the Application Code</h2>If your issue is working what part of the application code triggered the execution of a given SQL statement, a neat feature of the log4jdbc loggers is including the class & method-name of the code that invoked the JDBC driver. As there may be a few layers between your code and the JDBC driver (hibernate > application server connection pool, etc) you can tell it what level you what to capture from.<ol type="a"><li>change log level to <code>DEBUG</code><br />
<code>log4j.logger.jdbc.sqltiming=<b>DEBUG</b>,Log4JDBC</code><br />
</li>
<li>set the system property <code>log4jdbc.debug.stack.prefix</code><br />
<code>-Dlog4jdbc.debug.stack.prefix=<i>com.example</i></code><br />
</li>
</ol>
Log statements will then be in the form:<pre>DEBUG [01 Nov 2013 12:30:00,000 jdbc.sqltiming]: com.example.PersonDAO.findPerson(PersonDAO.java:111)
2. SELECT NAME FROM PERSON WHERE ID=54321
{executed in 53 msec}
</pre><br />
NB: this extra logging adds a noticeable overhead to the database usage (and timings).<br />
<br />
<br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-12517595513152637342013-08-02T18:04:00.000+10:002013-08-02T18:04:10.188+10:00Tomcat IIS Connector "request entity is too large" <span class="daKeywords">Keywords:</span><br />
tomcat IIS IIS7 jk connector max_packet_size packetSize "The page was not displayed because the request entity is too large"<br />
<br />
<span class="daProblem">Problem:</span><br />
With IIS successfully configured with tomcat using the <a href="http://tomcat.apache.org/connectors-doc/">Apache Tomcat Connector</a> (aside: if you haven't got that far the <a href="http://www.iisadmin.co.uk/?p=72&page=2">IIS Admin Blog - How To Configure IIS 7.0 and Tomcat</a> is a good reference - with screenshots) you find that some users can access the web-apps ok, others cannot. They get a plain error page saying:<pre>The page was not displayed because the request entity is too large
</pre>How do you fix it?<br />
<br />
<span class="daSolution">Solution:</span><br />
The issue is with attributes in the request exceeding the AJP 8kb default (for me, the ISAPI redirector was logging the error was with the 'Authorization' attribute). You can increase this to <i>maximum</i> of 65Kb. <br />
<br />
This needs to be done in the tomcat-connector and tomcat itself. <br />
<br />
<h2>Step 1: Set <code>max_packet_size</code> in the worker definition</h2>In the <code>workers.properties</code> file referenced by the tomcat-connection definition, set the packet size to the maximum:<br />
<pre class="brush:text;">worker.<worker name>.max_packet_size=65536</pre>for example:<br />
<pre class="brush:text;">worker.ajp13w.max_packet_size=65536</pre>Check the <a href="http://tomcat.apache.org/connectors-doc/reference/workers.html">workers</a> documentation for more information. <br />
<br />
<h2>Step 2: Set <code>packetSize</code> in the AJP Connector definition</h2>In the <code>server.xml</code> configuration file for tomcat, set the packet size to the maximum:<br />
<pre class="brush:xml;"><Connector port="8009" protocol="AJP/1.3" redirectPort="8443" packetSize="65536"
tomcatAuthentication="false" /></pre>Check the <a href="http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html">AJP Connector</a> documentation for more information. <br />
<br />
<br />
You'll then need to restart tomcat and IIS Site for the changes to take effect (then hope for the best).<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-59269662661157837092013-07-01T10:11:00.000+10:002013-07-01T10:11:00.342+10:00Querying JSON using JSONPath<span class="daKeywords">Keywords:</span><br />
JSON query filter evaluate JSONPath expression<br />
<br />
<span class="daProblem">Problem:</span><br />
Dealing with code that's doing a fair bit of JSON processing (traversing object structures and collating the values) it leads to the question - is there a standard way to lookup or filter data from the JSON structure using a query or expression? <br />
<br />
The same question has been already been asked on <a href="http://stackoverflow.com/questions/777455/is-there-a-query-language-for-json#7812073">StackOverflow: Is there a query language for JSON?</a> and the answer is essentially that there are <i>many</i> approaches. There's another list of approaches with examples in <a href="http://orangevolt.blogspot.com.au/2012/12/8-ways-to-query-json-structures.html">8 ways to query json structures</a>. <br />
<br />
So if there's no '<i>standard</i>' approach (for example, backed by an RFC as is the case with <a href="http://json.org">JSON</a>), which approach should I pick?<br />
<br />
<br />
<span class="daSolution">Solution:</span><br />
<a href="http://goessner.net/articles/JsonPath">JSONPath</a> proposed by Stefan Goessner allows for XPath-like expressions to be evaluated against JSON. What's possible with the expression syntax seems to cover most of the traversal and collating scenarios I was interested in and the JavaScript implementation is remarkably lightweight (implemented as just one function <code>jsonPath(<object>, <expression>, <optional arguments object>)</code>). <br />
<br />
Here some extra expression examples (beyond those shown in the <a href="http://goessner.net/articles/JsonPath">JSONPath articles</a> and <a href="https://code.google.com/p/jsonpath/wiki/Javascript">jsonpath on Google Code</a>):<br />
<br />
<table id="expression_examples" class=""> <thead>
<tr>
<th align="left" style="background-color: #777; color: #fff">Expression</th>
<th align="left" style="background-color: #777; color: #fff">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="background-color: rgb(232, 238, 247);"><code style="background-color: rgb(232, 238, 247);">$</code></td>
<td style="background-color: rgb(232, 238, 247);">The root element (the same JSON back out - i.e. an identity transform).</td>
</tr>
<tr>
<td style="background-color: rgb(255, 255, 255);"><code style="background-color: rgb(255, 255, 255);">$.*</code></td>
<td style="background-color: rgb(255, 255, 255);">All child elements of the root.</td>
</tr>
<tr>
<td style="background-color: rgb(232, 238, 247);"><code style="background-color: rgb(232, 238, 247);">$.store.book</code></td>
<td style="background-color: rgb(232, 238, 247);">All book elements.</td>
</tr>
<tr>
<td style="background-color: rgb(255, 255, 255);"><code style="background-color: rgb(255, 255, 255);">$.store.book[1]</code></td>
<td style="background-color: rgb(255, 255, 255);">The second book element.</td>
</tr>
<tr>
<td style="background-color: rgb(232, 238, 247);"><code style="background-color: rgb(232, 238, 247);">$..price</code></td>
<td style="background-color: rgb(232, 238, 247);">The price of every element - result will be Numbers.</td>
</tr>
<tr>
<td style="background-color: rgb(255, 255, 255);"><code style="background-color: rgb(255, 255, 255);">$.store.book[?(@.isbn=='0-553-21311-3')]</code></td>
<td style="background-color: rgb(255, 255, 255);">The book element where isbn is '0-553-21311-3'.</td>
</tr>
<tr>
<td style="background-color: rgb(232, 238, 247);"><code style="background-color: rgb(232, 238, 247);">$.store.book[?(@.category=='fiction' && @.price > 10)]</code></td>
<td style="background-color: rgb(232, 238, 247);">The book element where category is 'fiction' <i>and</i> price is more than 10.</td>
</tr>
</tbody>
</table><br />
It seems like there's still some discussion around what's to be supported and there isn't exactly high activity on the project. So if using it, treat is as beta and evaluate if it does what you need. It's likely to be one of those things that once it gets past v0 there will be less (if any) changes to expect.<br />
<br />
Some things to look out for:<ul><li><b>Where's the latest version?</b><br />
Although the <a href="https://code.google.com/p/jsonpath/downloads/list">downloads page</a> says the latest version is 0.8.0, this few years old (2007). You can access later versions (of the JavaScript source) either via the <a href="http://jsonpath.googlecode.com/svn/trunk/src/js/">SVN path to the trunk</a> or via the <a href="https://code.google.com/p/jsonpath/source/browse/#svn%2Ftrunk%2Fsrc%2Fjs">Google Code Browser</a>. The javascript implementation lists the version as 0.8.5 - I'm not sure what the cycle is for getting this to 'release'.</li>
<li><b>No results returned as <code>false</code></b><br />
I'd expect this to be simply an empty array <code>[]</code>.</li>
<li><b>Results as Arrays of Arrays</b><br />
If querying a nested JSON structure of objects and the matching results match different parts of the tree, what you get back is a nested array structure indicating the relative location of the matches. I'd prefer to get this back as a <i>flattened</i> array. I guess the logic is that have the context of where the items were found and if you want, you can post-process (and flatten) the Arrays of Arrays - some useful approaches discussed on <a href="http://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript">StackOverflow:Merge/flatten an Array of Arrays in JavaScript?</a>.</li>
<li><b>the Object <i>and</i> it's properties in the results?</b><br />
In using the latest code mentioned above, it seems that - in some scenarios - where an object matches the expression the result includes the object <i>as well as</i> the properties as additional items in the result. For example:<br />
<table cellpadding="1" cellspacing="0"><tr>
<td><i>Instead of:</i></td>
<td><i>You get:</i></td>
</tr>
<tr>
<td valign="top"><pre>[
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}
]
</pre></td>
<td><pre>[
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
"fiction",
"Herman Melville",
"Moby Dick",
"0-553-21311-3",
8.99
]
</pre></td>
</tr>
</table>This wasn't the case with 0.8.0 and may change in future releases?</li>
</ul><br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-69457193096696654612013-06-04T12:43:00.000+10:002013-06-04T12:43:45.165+10:00Stop Chrome from Prerending URLs<span class="daKeywords">Keywords:</span><br />
Google Chrome prefetch POST prerender random timeout speculative sockets preconnections browser learning predict network actions<br />
<br />
<span class="daProblem">Problem:</span><br />
Chrome has become my browser of choice - it <i>seems</i> faster and is less reliant on the disk which is critical if you're on machine that's continually doing disk-intensive work (such as builds). <br />
<br />
That speed can come at a cost. Perhaps it was an update or perhaps because of the repetition of certain actions in a web-wizard style application in development but all of a sudden using Chrome was giving random unexpected results that weren't reproducible in other browsers. <br />
<br />
Tracing the server-side, it seems that URLs are being called - with GET requests - independently of my actions in the browser. These phantom requests include my credentials (HTTP BASIC auth) <i>and</i> session information (as cookies), but on the client-side (tracking Network in Developer Mode) there's no explanation for how/why/when these URLs are being hit. <br />
<br />
Is my browser possessed? <br />
<br />
<span class="daSolution">Solution:</span><br />
Short answer? YES, yes it is (kind of) possessed! What I'm seeing is Chrome <i>predicting</i> my next action in the web-application and hitting those URLs (on my behalf) in the interests of speed. It was initially hard to find good references for this because it seems to be referenced with various terms. Officially, it's "<i>Prerender</i>" and the Google Whitepaper "<a href="https://developers.google.com/chrome/whitepapers/prerender">Web Developer's Guide to Prerendering in Chrome</a>" describes it as:<br />
<br />
<blockquote cite="https://developers.google.com/chrome/whitepapers/prerender"><i>Prerendering</i> extends the concept of prefetching. Instead of just downloading the top-level resource, it does all of the work necessary to show the page to the user—without actually showing it until the user clicks. Prerendering behaves similarly to if a user middle-clicked on a link on a page (opening it in a background tab) and then later switched to that tab. However, in prerendering, that "background tab" is totally hidden from the user, and when the user clicks, its contents are seamlessly swapped into the same tab the user was viewing. From the user’s perspective, the page simply loads much faster than before.<br />
</blockquote><br />
As mentioned in the quote, it's separate to "<i>Prefetching</i>" - which is the mechanism where a page can <i>explicitly</i> flag a URL as safe/recommended to begin fetching. <br />
<br />
If this was a chess program, it's like the browser is thinking a few moves ahead but instead of just anticipating moves, it's actually making them. <br />
<br />
As raised (and debated) in <a href="https://code.google.com/p/chromium/issues/detail?id=85229">Chromium Issue 85229</a> - this time under the term "<i>speculative sockets</i>" - there's <i>no way</i> for the server/application to opt-out or ask it not to do this. <br />
<br />
You can view diagnostics for what URLs are being Prerendered by opening the following in a tab (if you're experiencing erroneous/random behaviour it can make for interesting reading):<pre>chrome://net-internals/#prerender</pre><br />
Shouldn't GET requests be safe? As discussed in <a href="http://fusiongrokker.com/post/on-chrome-and-url-pre-fetching">On Chrome and URL <i>Pre-fetching</i></a>, yes but surely not <i>always</i> 100% safe. If you have an app that has URLs that only ever get POST requests there's nothing stopping Chrome from hitting these with Prerender GETs - and if the URLs (for convenience) handle the GET requests you could be trouble. Which leads to some inconsistencies in the above mentioned whitepaper for "Situations in which prerendering is aborted" (<i>"...Chrome may run into a situation that could potentially lead to user-visible behavior that is incorrect"</i>):<ul><li>POST, PUT, and DELETE XMLHTTPRequests<br/>False: although in your usage of an application/site a URL may only ever be invoked via POST, you can't stop it <i>attempting</i> the same URL with a GET, just minus the parameters.</li><li>Developer Tools is open<br/>False: In my usage anyway, using the Developer tools (trying to track Network requests) will not stop the Prerender requests being made.</li></ul><br />
Which (finally) leads to the solution - <b>turn off Prerending</b>. The whitepaper has a section titled "Ensuring you have prerender turned on" (despite it being enabled by default). So disabling it involves following the reverse:<ol><li>Click the 'three bars' icon in the top right of Chrome.</li>
<li>Click 'Settings'</li>
<li>Click 'Show advanced settings...'</li>
<li>Under 'Privacy'<ul><li>un-check the option 'Predict network actions to improve page load performance'</li><li>un-check 'Use a prediction service to help complete searches and URLs typed in the address bar'<br/>(this specifically relates to prefetch/prerender of URLs typed into the 'Omnibox' address bar - Chrome will actually be calling up the suggested sites in the background if they happen to be URLs you commonly select)</li></ul></li>
<li>Open a new tab and paste in "<code>chrome://net-internals/#prerender</code>"<br/>Confirm that it lists:<ul><li>Prerender Enabled: false</li><li>Prerender Omnibox Enabled: false</li></ul></li>
</ol><br />
<br />
<span class="daNotes">Notes:</span><br />
There is some confusion about the requests being made for Prerender and reports of Chrome making multiple (and unnecessary) background requests for the favicon - e.g. <a href="https://code.google.com/p/chromium/issues/detail?id=39402">Issue 39402</a>. At the server-side it will be clear that Prerender requests are for URLs that you tend to access, before you actually access them rather than URLs ending in <code>/favicon.ico</code>. There doesn't seem to be a way to disable favicon 'polling' but the above mentioned issue seems to indicate improvements were being considered to reduce the server load. <br />
<br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-84850808667852184772013-04-07T16:41:00.000+10:002013-04-07T16:41:00.453+10:00Capture console output in ant - for any command or task - using Record<span class="daKeywords">Keywords:</span> <br />
ant capture task console output stdout stderr javac jspc "Problems opening file using a recorder entry" absolute path<br />
<br />
<span class="daProblem">Problem:</span> <br />
Many tasks include options to capture output. Each of them different, such as exec - with the <a href="http://ant.apache.org/manual/Types/redirector.html">redirector</a> option; <a href="http://ant.apache.org/manual/Tasks/java.html">java</a> - with the <code>@output</code> attribute. What if you want to capture the output (stderr and stdout) from a task that doesn't support output capture (such as <code>javac</code>) or you'd like more control - start|stop|start appending output from many commands to shared file(s)?<br />
<br />
<span class="daSolution">Solution:</span> <br />
<a href="http://ant.apache.org/manual/Tasks/recorder.html">Record</a> is the solution. Just <i>BEWARE</i> the <code>@name</code> attribute is treated as <i>plain file path</i> rather than a File attribute as in many other ant tasks. This means if supplied with a relative path it will be relative to where you're running ant from - a problem if you have ant scripts invoking other ant scripts. When path issues occur, you'll get this error:<pre>Problems opening file using a recorder entry
</pre><br />
Run ant with the <code>-v</code> option to get the full stack trace of the <code>IOException</code>. You'll see what path it's attempted - and failed - to use.<br />
<br />
<i>ALWAYS</i> use absolute paths and you'll (hopefully) be fine.<br />
<br />
To start recording:<pre class="brush:xml;"><!-- (1) guarantee that you have an absolute path to the log file by setting a property with @location as the relative reference -->
<property name="build.logpath" location="${a.build.location}/sub_folder/log_file.log"/>
<!-- (2) start recording -->
<record action="start" name="${build.logpath}" loglevel="verbose"/>
</pre><br />
All tasks that follow will have the console output (<i>and logging</i> if you set the loglevel attribute) go to the capture file:<pre class="brush:xml;"><jasper2 ... />
<javac ... />
etc.
</pre><br />
Then to stop:<pre class="brush:xml;"><record action="stop" name="${build.logpath}"/>
</pre><br />
Easy as that. <br />
<br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-88746013281116811232013-03-29T14:13:00.000+11:002013-04-05T14:36:41.959+11:00Use javascript to set text (with newlines) into a textarea - for IE and Firefox<span class="daKeywords">Keywords:</span><br />
javascript jquery textarea DOM innerHTML newlines carriage return whitespace IE firefox chrome<br />
<br />
<span class="daProblem">Problem:</span> <br />
Setting text with newlines into a textarea using the <code>innerHTML</code> attribute:<pre class="brush:html;highlight:[15]"><textarea id="source" rows="4" cols="50">
A
B
C
</textarea>
<button onclick="copyText();return false;">copy -></button>
<textarea id="target" rows="4" cols="50">
</textarea>
<script type="text/javascript">
function copyText() {
var sourceField = document.getElementById('source');
var targetField = document.getElementById('target');
targetField.innerHTML = sourceField.value;
}
</script>
</pre><br />
Works in "most" browsers but in IE the text put into the textarea has the newline characters <i>stripped out</i> (replaced with a single space character). Is there a way to make this work in IE? ... and most other browsers? <br />
<br />
<span class="daSolution">Solution:</span> <br />
To make it work in IE, setting the text via <code><i>inputField</i>.setAttribute("value", <i>[your text]</i>);</code> will preserve the newlines (i.e. the "\n" character in javascript)<pre class="brush:js;highlight:[3]">var sourceField = document.getElementById('source');
var targetField = document.getElementById('target');
targetField.setAttribute("value",sourceField.value);
</pre><br />
Only problem is that setting the attribute alone is not enough for <i>Firefox (& Chrome - all WebKit?)</i>. For the above example, the target field will not appear to have the value from the source (though the <i>DOM</i> will have the value). To get them all to work? Contrive the order in which you set things:<pre class="brush:js;highlight:[3,4,5]">var sourceField = document.getElementById('source');
var targetField = document.getElementById('target');
var text = sourceField.value;
targetField.innerHTML = text; // now Firefox (& Chrome) are happy - but IE has the text as one line
targetField.setAttribute("value", text); // now IE has the text as multiple lines - the change should be imperceptible
</pre><br />
The same code using jQuery (note that jQuery's <code>html()</code> function will still use innerHTML ultimately so is subject to same IE issue with newlines being stripped):<pre class="brush:js;">jQuery(document).ready(function($){
var text = $(sourceField).val();
$(targetField).html(text);
$(targetField).val(text);
});
</pre><br />
<span class="daNotes">Notes:</span> <br />
Use of <code>innerHTML</code> for managing textarea content - and keeping it in-synch with the DOM - was discussed in the previous post: <a href="http://dev-answers.blogspot.com.au/2007/08/firefox-does-not-reflect-input-form.html">Firefox does not reflect input form field values via innerHTML</a>. I'll update that post accordingly ... <br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-75633574079075576792012-11-30T14:54:00.004+11:002013-04-09T11:48:16.453+10:00Using CXF in Containers with JAX-WS handling - WebSphere/WebLogic<span class="daKeywords">Keywords:</span><br />
cxf jax-ws websphere weblogic annotation DisableIBMJAXWSEngine Ignore-Scanning-Packages Ignore-Scanning-Archives prefer-web-inf-classes prefer-application-packages prefer-application-resources<br />
<br />
<span class="daProblem">Problem:</span><br />
So CXF is your chosen JAX-WS framework for your application - perhaps because you want your appplication to work the same way in every servlet container - tomcat included - or because you can't avoid the need to reference the implementation rather than just the pure JAX-WS spec (access to the http-session for example). While these reasons seem valid they seem to have been considered as an afterthought in containers with built in JAX-WS handling - such as WebSphere and WebLogic. <br />
<br />
So you follow the CXF notes and perhaps blog/mail-list posts and either are in the state where: (a) the application is not working or (b) is working but you're not sure how or why. What steps can you perform to guarantee successful deployment, and (if possible) can you understand the context for them - so you can decide if they're needed for example. <br />
<br />
<span class="daSolution">Solution:</span><br />
The following are useful references:<ul><li>CXF Notes - <a href="http://cxf.apache.org/docs/application-server-specific-configuration-guide.html">Application Server Specific Configuration Guide</a></li>
<li>WebSphere - <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Ftwbs_thirdparty.html">Using a third-party JAX-WS Web services engine</a></li>
<li>WebSphere - <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.doc%2Finfo%2Fae%2Fae%2Ftrun_app_reduce_annot.html">Reducing annotation searches during application deployment</a></li>
<li>WebLogic - <a href="http://docs.oracle.com/cd/E24329_01/web.1211/e21049/weblogic_xml.htm">Deployment Descriptor Reference</a></li>
</ul><br />
Normally for these container/class-loader issues you can get the desired behaviour by simply getting the container to load the application's libraries first (parent last). The complication in this case is the annotation processing, which seems (in my testing at least) can happen independently of the annotation processing implementation - particularly for the association of <code>@Resource</code> references. <br />
<br />
To get past this, there's essentially three areas to cover:<ol><li>Supply JAX-WS annotation processing libraries (geronimo) that will override the container defaults - this includes all libraries that the CXF framework and annotation processing require - because <i>nothing</i> can be used from the container (parent)</li>
<li>Tell the container you're handling annotations - explicitly</li>
<li>Setup Parent-Last Class-loading - get the container to use your applications libraries before its own</li>
</ol><br />
<h2>Step 1: Supply JAX-WS annotation processing libraries and dependencies</h2>There's a longer list of libraries in the CXF Notes but many of these are not specifically essential to the JAX-WS issue (the latest JAXB libraries for example will be required by CXF in a tomcat deployment). These are the libraries that <i>appear</i> to be need in addition to those that would have otherwise been included with the application:<ul><li><code>geronimo-annotation_1.0_spec-1.1.1.jar</code> - Annotation Processing</li>
<li><code>geronimo-jaxws_2.2_spec-1.1.jar</code> - Runtime Override</li>
<li><code>geronimo-stax-api_1.0_spec-1.0.1.jar</code> - Runtime Override</li>
<li><code>geronimo-ws-metadata_2.0_spec-1.1.3.jar</code> - Annotation Processing</li>
<li><code>stax2-api-3.1.1.jar</code> - Runtime Override</li>
<li><code>woodstox-core-asl-4.1.1.jar</code> - Library Requirement</li>
</ul>geronimo and woodstox/stax2 are the same Apache license as CXF and these libraries are supplied as part of the CXF distribution. In WebSphere you'll know it's taken effect as in deployment you'll see:<pre class="brush:plain">[19/10/12 8:34:46:641 EST] 00000044 AbstractInjec W CWNEN0070W: The javax.annotation.Resource annotation class will not be recognized because it was loaded from the
file:/E:/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/SERVERNode01Cell/example-app.ear/lib/geronimo-annotation_1.0_spec-1.1.1.jar location rather than from a product class loader.
[19/10/12 8:34:46:645 EST] 00000044 AbstractInjec W CWNEN0070W: The javax.xml.ws.WebServiceRef annotation class will not be recognized because it was loaded from the
file:/E:/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/SERVERNode01Cell/example-app.ear/lib/geronimo-jaxws_2.2_spec-1.1.jar location rather than from a product class loader.</pre>The "Runtime Override" libraries listed above are essential as the overridden annotation processing code can not load certain classes from the parent - this may include classes from <code>javax.xml.*</code>. These 'parent prevention' issues are most likely going to be reported as <code>java.lang.VerifyError</code>. In WebSphere for example you'll encounter 'parent prevention' issues as:<pre class="brush:plain">Caused by: java.lang.VerifyError: JVMVRFY013 class loading constraint violated;
class=org/apache/cxf/jaxws/context/WebServiceContextImpl,
method=getEndpointReference([Lorg/w3c/dom/Element;)Ljavax/xml/ws/EndpointReference;,
pc=0
at java.lang.J9VMInternals.verifyImpl(Native Method)
at java.lang.J9VMInternals.verify(J9VMInternals.java:85)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:162)
at org.apache.cxf.jaxws.context.WebServiceContextResourceResolver.resolve(WebServiceContextResourceResolver.java:61)
</pre><h2>Step 2: Tell the container you're handling annotations</h2>This seems the strangest part but both WebSphere and WebLogic will continue to report errors - in particular about the <code>@Resource</code> annotation. For example, on WebSphere:<pre class="brush:plain">[19/10/12 17:11:03:261 EST] 00000053 webapp E com.ibm.ws.webcontainer.webapp.WebAppImpl populateJavaNameSpace SRVE8084E: An unexpected internal server error occurred while populating the namespace.
com.ibm.wsspi.injectionengine.InjectionException: CWNEN0044E: A resource reference binding could not be found for the following resource references [org.example.hello.HelloSoapService/context], defined for the example-app component.
at com.ibm.wsspi.injectionengine.InjectionProcessor.resolveInjectionBindings(InjectionProcessor.java:1208)</pre>For example, on WebLogic:<pre class="brush:plain"><24/10/2012 2:17:27 PM EST> <Error> <J2EE> <BEA-160223>
<The resource-env-ref 'org.example.hello.HelloSoapService/context' declared in the standard descriptor or annotation has no JNDI name mapped to it.
The resource-env-ref must be mapped to a JNDI name using the resource-env-description element of the weblogic proprietary descriptor or corresponding annotation.>
</pre><h3>For <u>WebSphere</u> - Disable and Ignore Annotation Scanning</h3>There are ways to configure this globally - in the application server settings and configuration. I'll only note here the application-specific approach. This involves setting attributes in the <code>META-INF/MANIFEST.MF</code> of the war file.<ol><li><code>DisableIBMJAXWSEngine</code>: true</li>
<li><code>Ignore-Scanning-Packages</code>: comma-separated list of packages where there are service implementations - and use of the <code>@Resource</code> and <code>@WebService</code> annotations</li>
<li><code>Ignore-Scanning-Archives</code>: comma-separated list of jar-file libraries where there are service implementations - and use of the <code>@Resource</code> and <code>@WebService</code> annotations</li>
</ol>You don't necessarily have to do both 2 & 3 - use 2 if implementations are in <code>(war-app)/WEB-INF/classes</code> for example. It does seem setting the Ignore-Scanning-Archives setting can significantly speed application deployment - and is harmless if there is no annotation processing required. Hand-coding MANIFEST files is risky - I'd recommend using an ant task (and define all three attributes):<pre class="brush:xml"><target name="dist" description="make the war and ear">
<!-- list of packages with WS implementations - which should be ignored by container annotation processing -->
<property name="service.packages">
org.example.hello,
org.example.goodbye
</property>
<loadresource property="service.packages.delim">
<propertyresource name="service.packages"/>
<filterchain>
<tabstospaces/>
<deletecharacters chars=" "/>
<striplinebreaks/>
</filterchain>
</loadresource>
<path id="webapp.archives">
<fileset dir="./example-app/WEB-INF/lib">
<include name="**/*.jar"/>
</fileset>
</path>
<pathconvert property="webapp.archives.delim" refid="webapp.archives" pathsep="," dirsep="/">
<map from="${basedir}/example-app/WEB-INF/lib/" to=''/>
</pathconvert>
<!-- Define META-INF attributes -->
<manifest file="./example-app/META-INF/MANIFEST.MF" mode="update" flattenAttributes="true">
<attribute name="DisableIBMJAXWSEngine" value="true"/>
<attribute name="Ignore-Scanning-Packages" value="${service.packages.delim}"/>
<attribute name="Ignore-Scanning-Archives" value="${webapp.archives.delim}"/>
</manifest>
<copy todir="./example-app/WEB-INF/lib">
<fileset dir="./runtime">
<include name="**/*.*"/>
</fileset>
</copy>
<jar destfile="example-app.war" basedir="./example-app/"
manifest="./example-app/META-INF/MANIFEST.MF"/>
<ear destfile="example-app.ear" appxml="metadata/application.xml">
<fileset dir="." includes="example-app.war"/>
<metainf dir="metadata" includes="*.*" excludes="application.xml"/>
</ear>
</target>
</pre><h3>For <u>WebLogic</u> - Prefer Packages and Resources</h3>In the <code>(ear-app)/META-INF/weblogic-application.xml</code> you must explicitly preference the packages supplied as part of the CXF solution <i>and</i> the service resources these libraries include:<pre class="brush:xml"><?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
<xml>
<parser-factory>
<saxparser-factory>org.apache.xerces.jaxp.SAXParserFactoryImpl</saxparser-factory>
<document-builder-factory>org.apache.xerces.jaxp.DocumentBuilderFactoryImpl</document-builder-factory>
<transformer-factory>org.apache.xalan.processor.TransformerFactoryImpl</transformer-factory>
</parser-factory>
</xml>
<application-param>
<param-name>webapp.encoding.default</param-name>
<param-value>UTF-8</param-value>
</application-param>
<prefer-application-packages>
<!-- // for logging -->
<package-name>org.apache.log4j.*</package-name>
<!-- // for jaxb -->
<package-name>com.sun.xml.*</package-name>
<!-- // for apache commons lang/io -->
<package-name>org.apache.commons.*</package-name>
<!-- // for spring/hibernate -->
<package-name>antlr.*</package-name>
<package-name>org.springframework.*</package-name>
<!-- // for jstl -->
<package-name>javax.servlet.jsp.jstl.*</package-name>
<!-- // for jax-ws -->
<package-name>javax.jws.*</package-name>
<package-name>javax.ws.*</package-name>
<!-- // xml processing -->
<package-name>javax.xml.*</package-name>
<package-name>javax.xml.stream.*</package-name>
<package-name>org.xml.sax.*</package-name>
<package-name>org.w3c.*</package-name>
<package-name>org.apache.xmlcommons.*</package-name>
<package-name>org.apache.xml.serializer.*</package-name>
<package-name>org.apache.xerces.*</package-name>
<package-name>org.apache.xalan.*</package-name>
<package-name>com.ctc.wstx.*</package-name>
<package-name>org.codehaus.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
<resource-name>META-INF/services/javax.ws.rs.ext.RuntimeDelegate</resource-name>
<resource-name>META-INF/services/javax.xml.bind.JAXBContext</resource-name>
<resource-name>META-INF/services/javax.xml.datatype.DatatypeFactory</resource-name>
<resource-name>META-INF/services/javax.xml.parsers.DocumentBuilderFactory</resource-name>
<resource-name>META-INF/services/javax.xml.parsers.SAXParserFactory</resource-name>
<resource-name>META-INF/services/javax.xml.stream.XMLEventFactory</resource-name>
<resource-name>META-INF/services/javax.xml.stream.XMLInputFactory</resource-name>
<resource-name>META-INF/services/javax.xml.stream.XMLOutputFactory</resource-name>
<resource-name>META-INF/services/javax.xml.transform.TransformerFactory</resource-name>
<resource-name>META-INF/services/javax.xml.validation.SchemaFactory</resource-name>
<resource-name>META-INF/services/javax.xml.ws.spi.Provider</resource-name>
<resource-name>META-INF/services/javax.xml.xpath.XPathFactory</resource-name>
<resource-name>META-INF/services/org.apache.cxf.bus.factory</resource-name>
<resource-name>META-INF/services/org.apache.xalan.extensions.bsf.BSFManager</resource-name>
<resource-name>META-INF/services/org.apache.xml.dtm.DTMManager</resource-name>
<resource-name>META-INF/services/org.codehaus.stax2.validation.XMLValidationSchemaFactory.dtd</resource-name>
<resource-name>META-INF/services/org.codehaus.stax2.validation.XMLValidationSchemaFactory.relaxng</resource-name>
<resource-name>META-INF/services/org.codehaus.stax2.validation.XMLValidationSchemaFactory.w3c</resource-name>
<resource-name>META-INF/services/org.osgi.framework.launch.FrameworkFactory</resource-name>
<resource-name>META-INF/services/org.relaxng.datatype.DatatypeLibraryFactory</resource-name>
<resource-name>META-INF/services/org.w3c.dom.DOMImplementationSourceList</resource-name>
<resource-name>META-INF/services/org.xml.sax.driver</resource-name>
<!-- // geronimo (at present) has no service such declaration (glassfish and others do) - include for future reference -->
<resource-name>META-INF/services/com.sun.xml.ws.spi.db.BindingContextFactory</resource-name>
</prefer-application-resources>
</weblogic-application></pre><h2>Step 3: Setup Parent-Last Class-loading</h2>This is probably the easiest step. <h3>For <u>WebSphere</u> - set flags during deployment</h3>Note that this should be set at the ear and war (web module) level. <h3>For <u>WebLogic</u> - set prefer-web-inf-classes</h3>This doesn't seem to be a comprehensive setting based on what is required in the <code>weblogic-application.xml</code> file, but in the <code>(war-app)/WEB-INF/weblogic.xml</code> file, ensure <code>prefer-web-inf-classes</code> is set to true:<pre class="brush:xml"><?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<jsp-descriptor>
<keepgenerated>false</keepgenerated>
<page-check-seconds>-1</page-check-seconds>
<precompile>true</precompile>
<precompile-continue>true</precompile-continue>
<verbose>false</verbose>
</jsp-descriptor>
<container-descriptor>
<servlet-reload-check-secs>-1</servlet-reload-check-secs>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>
</pre><br />
Happy CXF servicing. <br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com1tag:blogger.com,1999:blog-24384544.post-57112012791799645872012-10-23T12:53:00.000+11:002012-10-23T12:56:59.530+11:00Stop Hibernate info level logging to Console in WebSphere<span class="daKeywords">Keywords:</span><br />
websphere hibernate logging info commons logging log4j info SystemOut.log Console stdout WAS7 WAS8.5<br />
<br />
<span class="daProblem">Problem:</span> <br />
The application is packaged with hibernate and configured with log4j logging (to a rolling, application-specific file - hibernate set to WARN level logging) and deployed to WebSphere with <b>parent last</b> class loading. <br />
<br />
Despite all this <i>info</i>-level messages are being output to the WebSphere system-out/console log (in <code>WAS_HOME\profiles\[profile_name]\logs\[server_name]\SystemOut.log</code>).<br />
<br />
Why is the application log4j configuration (in <code>log4j.properties</code>) being ignored and how can the application's hibernate logging be diverted away from the console?<br />
<br />
<span class="daSolution">Solution:</span><br />
Various resources on the web describe configuring WebSphere logging or hibernate logging but the bottom of this post on <a href="http://www.basilv.com/psd/blog/2008/hibernate-and-logging">Hibernate and Logging</a> specifically describes this 'leaking' of log configuration/output and how to resolve it. <br />
<br />
Create a <code>commons-logging.properties</code> with the content:<pre>org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
</pre>... and put this file in the application's classpath (<code>WEB-INF/classes</code> for example). <br />
<br />
<br />
<br />
<span class="daNotes">Notes:</span> <br />
By default, WebSphere Application Server is installed to use info level tracing (<i>for all loggers that it knowns about</i>). In WAS 8.5 you'll see this in the SystemOut.log:<pre>[22/10/12 12:00:00:000 EST] 00000001 ManagerAdmin I TRAS0017I: The startup trace state is <b style="color:red">*=info</b>.
</pre><br />
You can edit this by going to (in WAS 8.5) Application Servers > [server_name] > Troubleshooting | Change log detail levels. You can specify the logging definition in plain text. For example, turning default logging to <code>audit</code>-level and disabling logging for the verbose <code>com.ibm.ws.webcontainer.annotation</code> module (this is a ':' delimited list):<pre>*=audit: com.ibm.ws.webcontainer.annotation=off
</pre><br />
Alternatively, use the "Components and Groups" section of the interface to expand items of the "tree" and right-click to select custom logging levels for a given "node" (NB for log4j users, the log levels may not match log4j - eg "audit" and "warning" instead of "warn").<br />
<br />
Also interesting to note is that without the <code>commons-logging.properties</code> file defined in your web-app you will see <i>every</i> package from your application(s) and their libraries (where classes include logging definitions) included in this "Components and Groups" interface. Therefore if you see <code>org.hibernate.*</code> disappear from this interface you can be certain the configuration has worked. <br />
<br />
<br />
<br />
Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-39463686809839889882012-07-25T17:12:00.000+10:002012-07-27T10:16:21.637+10:00Managing Oracle JDBC Memory Usage - Executive Summary<span class="daKeywords">Keywords:</span> <br />
Oracle JDBC memory leak usage java.lang.OutOfMemoryError fetchSize white paper summary 10g 11.2<br />
<br />
<span class="daProblem">Problem:</span><br />
So there appears to be memory issues with your system. Oracle JDBC drivers seem like the prime candidate (based on the heap dumps). The <a href="http://www.oracle.com/technetwork/database/enterprise-edition/memory.pdf">Oracle JDBC Memory Management</a> white paper says as much:<br />
<blockquote>The Oracle JDBC drivers can use large amounts of memory. This is a conscious design choice, to trade off large memory use for improved performance. For the most part and for most users this has proved to be a good choice. Some users have experienced problems with the amount of memory the JDBC drivers use.</blockquote><br />
The white paper is only a dozen or so pages, but it seems each JDBC version introduces new connection properties or changes the meaning of previously used properties. Is there an executive-summary/cheat-sheet/quick-reference that would essentially say what you can do for a given version?<br />
<br />
<span class="daSolution">Solution:</span><br />
There doesn't seem to be, but I'll have a go ...<br />
<br />
First, some summary points:<ul><li>From 9i to 10g performance of the JDBC drivers has been improved "... on average about 30% faster".</li>
<li>This was achieved by a greater use a caches. The justification being "memory is relatively cheap".</li>
<li>In large scale applications with complex (and batch) data usage, there seem to be two key caches that may cause memory usage issues - the "Implicit Statement Cache" and the "Internal Buffer Cache".</li>
<li>Tuning the caches can be done via connection properties (all of which can also be defined as system "-D" properties). <br />
Tuning should be done in consideration of:<br />
<ul><li>the table design (column types and sizes)</li>
<li>the query design (columns needed / batches)</li>
<li>the fetch size. Setting this incorrectly will definitely cause OutOfMemoryErrors - as seen in <a href="https://issues.apache.org/jira/browse/JCR-2892">JCR-2892</a>.</li>
</ul></li>
</ul><br />
Now, for the connection properties:<br />
<table border="1"><thead>
<tr> <td rowspan="2" width="15%"><br />
<b>Property</b><br />
</td> <td rowspan="2" width="10%"><br />
<b>Default</b><br />
</td> <td rowspan="2" width="35%"><br />
<b>Notes</b><br />
</td> <td colspan="4" width="40%"><br />
<div style="text-align:center"><b>Applicable for Version</b></div></td> </tr>
<tr> <td><br />
<b>10.0.2.4</b><br />
</td> <td><br />
<b>11.1.0.6.0</b><br />
</td> <td><br />
<b>11.1.0.7.0</b><br />
</td> <td><br />
<b>11.2</b><br />
</td> </tr>
</thead> <tbody>
<tr> <td><br />
<code>oracle.jdbc.freeMemoryOnEnterImplicitCache</code><br />
</td> <td><br />
<span style="font-family:monospace;">false</span><br />
</td> <td><br />
When <span style="font-family:monospace;">true</span> row-data buffers are cleared when a PreparedStatement is cached (in the "Implicit Statement Cache"). <br />
</td> <td><br />
Yes (new)<br />
</td> <td colspan="3"><br />
Ignored<br />
(from 11.1.0.6.0 onwards, buffers are put in a new "Internal Buffer Cache")<br />
</td> </tr>
<tr> <td><br />
<code>oracle.jdbc.maxCachedBufferSize</code><br />
</td> <td><br />
<span style="font-family:monospace;">Integer.MAX_VALUE<br />
(2,147,483,647 ~ 2Gb)</span><br />
</td> <td><br />
Sets an upper limit on the "Internal Buffer Cache".<br />
Look out for the change in meaning from 11.1.0.7 to 11.2 - though if you use a value >30 in 11.2 it will revert to treating it as an integer. Oracle recommends: "... start with 18. If you have to set the value to less than 16, you probably need more memory."<br />
Each connection will (may?) have its own buffer cache. So in a connection pool setup multiply the pool-size by the maxCachedBufferSize. <br />
</td> <td><br />
N/A (no "Internal Buffer Cache")<br />
</td> <td><br />
No (no way to set the size)<br />
</td> <td><br />
Yes<br />
Set as an <b><i>integer</i></b> value.<br />
102400 ~ 100Kb<br />
</td> <td><br />
Yes<br />
Set as a <b><i>log2</i></b> value.<br />
18 = 2^18 = 262,144 ~ 256Kb<br />
</td> </tr>
<tr> <td><br />
<code>oracle.jdbc.useThreadLocalBufferCache</code><br />
</td> <td><br />
<span style="font-family:monospace;">false</span><br />
</td> <td><br />
By storing the buffer cache as a TreadLocal instead of on the Connection you'll save memory if (and only if) there are less Threads than Connections. Avoid if using code that uses Connections across Threads. <br />
</td> <td><br />
N/A<br />
</td> <td><br />
N/A<br />
</td> <td><br />
Yes (new)<br />
</td> <td><br />
Yes<br />
</td> </tr>
<tr> <td><br />
<code>oracle.jdbc.implicitStatementCacheSize</code><br />
</td> <td><br />
<span style="font-family:monospace;">0</span><br />
</td> <td><br />
An <i>initial</i> size for the "Implicit Statement Cache". But it doesn't seem that setting it to 0 or -1 will disable it, so it can perhaps be ignored for memory management issues - it may improve performance. <br />
</td> <td><br />
N/A<br />
</td> <td><br />
N/A<br />
</td> <td><br />
N/A<br />
</td> <td><br />
Yes (new)<br />
</td> </tr>
</tbody> </table>Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-10142341601919812672012-04-20T17:15:00.001+10:002012-04-23T11:41:53.846+10:00Running Native SQL deletes or updates via Hibernate<span class="daKeywords">Keywords:</span><br />
hibernate manual native SQL update delete bulkUpdate child table spring<br />
<br />
<span class="daProblem">Problem:</span><br />
Probably not the best idea but for performance, limitations in hibernate mappings or errors in the objects you find it'd be much easier to just run some manual SQL. Can you do this <i>via</i> hibernate? <br />
<br />
<span class="daSolution">Solution:</span><br />
Yes you can, hibernate call this "<a href="http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html">Native SQL</a>". This is fairly well document, but I noticed its missing an example of doing a manual update/delete - where the result is not going to give you a <code>list()</code> of anything.<br />
<br />
For <code>Query</code> you make via <code>createSQLQuery(...)</code>, use <code>executeUpdate()</code> which returns the number of rows effected. <br />
<br />
Here an example (using the CATS/DOGS table names from the hibernate document):<pre class="brush:java">Query deleteQuery = session.createSQLQuery(
"delete from CATS "
+ "where DOG_ID in ( "
+ "select d.ID from DOGS d "
+ "where d.STATUS = ?)");
deleteQuery.setString(0, "VICIOUS");
int updated = deleteQuery.executeUpdate();
</pre><br />
If you're integrating with hibernate via spring, the same can be done via the template-callback mechanism (where your DAO extends <code>org.springframework.orm.hibernate3.support.HibernateDaoSupport</code>):<pre class="brush:java">Integer deletedData = (Integer)getHibernateTemplate().execute(new HibernateCallback () {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
// delete the data
Query deleteQuery = session.createSQLQuery(
"delete from CATS "
+ "where DOG_ID in ( "
+ "select d.ID from DOGS d "
+ "where d.STATUS = ?)");
deleteQuery.setString(0, "VICIOUS");
int updated = deleteQuery.executeUpdate();
}
});
if (log.isDebugEnabled()) {
log.debug("rows deleted from CATS: " + deletedData);
}
</pre><br />
<span class="daNotes">Notes:</span> <br />
If you're wondering if you can avoid hard coding the table references by asking hibernate for the table-name mapping, this does seem possible - <a href="http://stackoverflow.com/questions/634342/get-the-table-name-from-the-model-in-hibernate">Get the table name from the model in Hibernate</a> - but this approach doesn't seem to be "public" so may disappear. <br />
<br />
<br />Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-23034378691761182732012-03-30T15:32:00.000+11:002012-03-30T15:32:02.173+11:00javascript object keys being sorted in some browsers<span class="daKeywords">Keywords:</span><br />
javascript object associative array map keys sorted ordered chrome safari webkit<br />
<br />
<span class="daProblem">Problem:</span><br />
Is it the case that some browsers - WebKit, and possibly IE9 - are sorting the keys javascript objects (aka "associative-arrays", aka "maps")? <br />
<br />
Trying the following code (note the integer keys as strings is intentional): <br />
<pre class="brush:js;"> var x = new Object;
x["3"]="C";
x["2"]="B";
x["1"]="A";
JSON.stringify(x);
</pre><br />
Or as a 1-line snippet you can paste in a (modern) browser address bar:<br />
<pre class="brush:js;"> javascript:var x = new Object;x["3"]="C";x["2"]="B";x["1"]="A";JSON.stringify(x);
</pre><br />
You'll get the following in Firefox:<br />
<code>{"3":"C","2":"B","1":"A"}</code><br />
<br />
In Chrome you'll get:<br />
<code>{"1":"A","2":"B","3":"C"}</code><br />
<br />
Is this a bug? Can you not expect the order the keys are added to be preserved?<br />
<br />
<span class="daSolution">Solution:</span><br />
The short answer is <b>no</b> (though more appropriately but rude would be "why would you!?"). <br />
<br />
A translation in terms that a Java programmer may understand is think of the javascript object as a <code><a href="http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html">java.util.HashMap</a></code> despite the fact it behaves a bit like a <code><a href="http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html">java.util.LinkedHashMap</a></code> in Firefox and like a <code><a href="http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html">java.util.TreeMap</a></code> in WebKit. <br />
<br />
Don't code based on any expectation of the key order - which may need some thought if dealing with JSON representations of objects where there is an implicit order in the objects in "stringify-ied" form. <br />
<br />
Some thoughts on how to maintain an order are here - <a href="http://stackoverflow.com/questions/5773950/how-to-keep-an-javascript-object-array-ordered-while-also-maintaining-key-lookup">How to keep an Javascript object/array ordered</a>.<br />Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-83959601384723668462011-10-19T12:18:00.000+11:002011-10-21T14:08:03.319+11:00Can not remote desktop - no Terminal Server License Servers available<span class="daKeywords">Keywords:</span><br />
remote desktop console disconnected terminal server license "no Terminal Server License Servers available"<br />
<br />
<span class="daProblem">Problem:</span><br />
On trying to remote desktop to a machine get the popup message:<br />
<pre>The remote session was disconnected because there are no Terminal Server License Servers available to provide a license.
Please contact the server administrator.</pre><br />
A quick search suggests:<br />
<ol><li>Restarting the "Terminal Server" can help<br />
but lets say (hypothetically) that we don't know where this is and/or how to do it.</li>
<li>Installing a Microsoft 'Hotfix'<br />
but after accepting the terms; filling in the hotfix request form; getting the email with the link to the hotfix executable - we (at the moment anyway) get a <code>500 Internal Server Error</code> on the MS hotfix download site.</li>
</ol><br />
If you just need to access the machine is there another option?<br />
<br />
<span class="daSolution">Solution:</span><br />
You can remote desktop to the "console" - this is effectively like 'physically' logging into the machine rather than a remote session. <br />
<pre>mstsc /console</pre><br />
or on Vista / Windows Server 2008:<br />
<pre>mstsc /admin</pre><br />
<code>mstsc</code> allows specifying the machine on the command line itself to avoid the computer selection popup (use <code>/help</code> option for other options):<br />
<pre>mstsc /v:remote-server /admin</pre><br />
Be aware that - if someone else had a console session on this machine they'd be kicked off. If you're logged on in console/admin mode anyone with access to the terminal - if it's plugged into a monitor for example - will see what you're doing. <br />
<br />Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-45977111494105872782011-09-21T16:27:00.002+10:002011-11-08T15:36:03.610+11:00Get the generated source code for JSPs in WebLogic<span class="daKeywords">Keywords:</span><br />
generated JSP java class source Oracle WebLogic line numbers<br />
<br />
<span class="daProblem">Problem:</span><br />
Given a stack trace such as the following:<br />
<pre>java.lang.NullPointerException
at jsp_servlet._web_45_inf._jsp._demo.__example._jspService(__example.java:117)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(ServletStubImpl.java:416)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:326)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:183)
at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:526)
at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:253)</pre><br />
It won't always be obvious what the issue in <code>example.jsp</code> corresponds to in the generated <code>__example.java</code>. How do you get at the generated source code for the JSPs?<br />
<br />
<span class="daSolution">Solution:</span><br />
The solution involves configuring a <code><i>[app_name]</i>/WEB-INF/weblogic.xml</code> file in your web-app. The documentation is in the WebLogic 10.3 docs - see <a href="http://download.oracle.com/docs/cd/E12840_01/wls/docs103/webapp/weblogic_xml.html#wp1038491">weblogic.xml Deployment Descriptor Elements</a> but keep in mind the file will be validated against the schema so the elements must be in the correct spot.<br />
<br />
Below is an example - defining the <code>jsp-descriptor</code> with <code>keepgenerated</code> and <code>working-dir</code> elements:<br />
<pre class="brush:xml; highlight: [6,7,8,9]"><?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<jsp-descriptor>
<keepgenerated>true</keepgenerated>
<working-dir>c:/my_folder/temp</working-dir>
</jsp-descriptor>
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app></pre>Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-73987555604684405932011-08-25T11:41:00.005+10:002011-08-25T14:29:26.779+10:00Beware: an empty string in Oracle is NULL<span class="daKeywords">Keywords:</span>
<br />empty string '' CLOB varchar varchar2 text null isnull nvl NullPointerException JDBC
<br />
<br /><span class="daProblem">Problem:</span>
<br />There's code that is (seemingly) working with writing strings to CLOB columns and with the code from a previous post (<a href="http://dev-answers.blogspot.com/2011/06/convert-oracle-clobs-to-string-in-jstl.html">Convert Oracle CLOBs to String</a>) the reading of strings from the CLOB columns is working ok too ... until we get to empty strings - could it be that something is converting <code>''</code> to <code>NULL</code>?
<br />
<br />Here's a test case:<pre>create table test_clobtext(
<br /> id number
<br /> , text clob
<br />);
<br />insert into test_clobtext values (1, 'some clob text');
<br />insert into test_clobtext values (2, '');
<br />select id, text from test_clobtext;</pre>
<br />You get:<pre> ID TEXT
<br />---------- ----------------
<br /> 1 some clob text
<br /> 2 </pre>
<br />What's the value in the 2nd row? You can use the <code>NVL()</code> (which is just like <code>ISNULL()</code>):<pre>
<br />select id, NVL(text,'IT IS A NULL') as text from test_clobtext;</pre>
<br />Shock, horror, this is the result:<pre> ID TEXT
<br />---------- ----------------
<br /> 1 some clob text
<br /> 2 IT IS A NULL </pre>
<br />... and because I'm still in disbelief:<pre>
<br />select id, NVL(text,'IT IS A NULL') as text from test_clobtext
<br />where text IS NULL;</pre>
<br />This is definitely the result:<pre> ID TEXT
<br />---------- ----------------
<br /> 2 IT IS A NULL </pre>
<br />
<br />So it's something to do with CLOBs? No, changing the text column to a <code>varchar</code> or <code>varchar2</code> and <span style="font-style:italic;">you will get the same result</span>! Is this right?
<br />
<br /><span class="daSolution">Solution:</span>
<br />This is apparently a well known issue (that I've only just stumbled across). A discussion is on <a href="http://stackoverflow.com/questions/203493/why-does-oracle-9i-treat-an-empty-string-as-null">stackoverflow: Why does Oracle treat empty string as NULL</a> which links to more details information on <a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5984520277372">ask-tom: Strings of Zero Length Not Equivalent To NULL</a>.
<br />
<br />It would seem that there are some scenarios where it won't be <code>NULL</code> but I can't reproduce this - changing the test case to have text as a <code>char(1)</code> still gives me <code>NULL</code> for the column.
<br />
<br />The bottom line is if you're working with strings/text in a Oracle database you must expect and handle <code>NULL</code> values coming back - there will be no way to distinguish between whether what was originally stored was actually a <code>NULL</code> or an empty string (<code>''</code>).
<br />
<br /><span class="daNotes">Notes:</span>
<br />If you're dealing with <code>CLOB</code> columns you do have the option of storing (vendor specific) <code>empty_clob()</code> where you do want to distinguish between the cell being set to empty from it not being set at all (ie <code>NULL</code>). This post "<a href="http://nuijten.blogspot.com/2009/11/empty-clob-is-not-null-its-not-null.html">An Empty Clob is not NULL</a>" is a good discussion.
<br />
<br />
<br />
<br />Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-19583595942192980532011-06-20T13:22:00.007+10:002011-08-25T14:36:08.435+10:00Convert Oracle CLOBs to String in JSTL and tag file<span class="daKeywords">Keywords:</span>
<br />java.lang.ClassCastException oracle.sql.CLOB cast java.lang.String CLOB jstl tag requestScope requestContext pageContext jspContext
<br />
<br /><span class="daProblem">Problem:</span>
<br />It's annoying when SQL that works for other vendors fails for a specific one ... in this case a "<code>text</code>" column in a schema is defined as "<code>clob</code>" in the corresponding oracle schema. Problem is that this is not necessarily equivalent - especially when querying the data. This is even more complex when the SQL is in JSTL. So with the JSTL code (where <code><span style="font-weight:bold;">textValue</span></code> is a CLOB):<pre>
<br /><sql:query var="data" >
<br /> select id,
<br /> textValue
<br /> from example
<br /> where id=?
<br /> <sql:param value="${param['id']}"/>
<br /></sql:query>
<br /><c:forEach items="${data.rows}" var="row">
<br /> <c:out value="${row.textValue}"/><br/>
<br /></c:forEach></pre>
<br />
<br />You get the result:<pre>
<br />oracle.sql.CLOB@e645e0
<br />oracle.sql.CLOB@1f58913
<br />oracle.sql.CLOB@fa6b82
<br />...</pre>
<br />
<br />Or if you try to use the <code>textValue</code> in something expecting a string, you'll get:<pre>java.lang.ClassCastException: oracle.sql.CLOB cannot be cast to java.lang.String</pre>
<br />
<br />How do you turn a Clob to a String without filling the JSP with vendor-specific code (leaving out the argument for not having SQL in the JSP for now)?
<br />
<br /><span class="daSolution">Solution:</span>
<br />Great discussion of this very issue is on the <a href="http://forums.oracle.com/forums/thread.jspa?threadID=168566">OTN Forum: JSP and CLOB</a>. It essentially involves putting the Clob to String code in a scriptlet. To keep this vendor-neutral and take some of the "ugliness" out of the JSP I'd opt for putting this code in a tag file and stick to referencing just the <code>java.sql.*</code> interfaces.
<br />
<br /><h2>Step 1: create a <code>/WEB-INF/tags/to-string.tag</code> tag file</h2>
<br />(Or in a subfolder - the <a href="http://java.sun.com/products/jsp/syntax/2.0/syntaxref2012.html">path must start with</a> <code>/WEB-INF/tags/..</code> if using the <code>tagdir</code> approach).
<br />
<br />This takes the CLOB (or other) column value and sets it back in the request context as a String.<pre>
<br /><%--
<br /> Can turn a CLOB to String for Oracle schema
<br />--%>
<br /><%@ tag body-content="empty" %>
<br /><%@ attribute name="var" required="true" type="java.lang.String" %>
<br /><%@ attribute name="value" required="true" type="java.lang.Object" %>
<br />
<br /><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<br />
<br /><%@ tag import="java.sql.*" %>
<br /><%@ tag import="javax.servlet.jsp.*" %>
<br /><%
<br /> String strValue = null;
<br /> if (value == null) {
<br /> strValue = ""; // NB: oracle empty string is null
<br /> } else if (value instanceof Clob) {
<br /> Clob clob = (Clob)value;
<br /> long size = clob.length();
<br /> strValue = clob.getSubString(1, (int)size);
<br /> } else {
<br /> strValue = value.toString();
<br /> }
<br /> jspContext.setAttribute(var, strValue, PageContext.REQUEST_SCOPE);
<br />%>
<br /></pre>
<br />
<br />In this tag file, <code>var</code> is the name of the variable to define in the requestScope. Note how this is done by referencing the <code>jspContext</code> variable.
<br />
<br /><h2>Step 2: Use the <code>to-string</code> tag for your <code>text</code>, <code>clob</code> or <span style="font-style:italic;">Other</span> columns</h2>
<br />This involves first defining the new taglib (putting all .tag files in tagdir in the JSP scope using the "eg" prefix in this example) and then simply using the eg:to-string tag to put the string-value of the column in a "local" requestScope variable.<pre>
<br /><span style="font-weight:bold;"><%@ taglib prefix="eg" tagdir="/WEB-INF/tags" %></span>
<br /><sql:query var="data" >
<br /> select id,
<br /> textValue
<br /> from example
<br /> where id=?
<br /> <sql:param value="${param['id']}"/>
<br /></sql:query>
<br /><c:forEach items="${data.rows}" var="row">
<br /> <span style="font-weight:bold;"><eg:to-string var="textValue" value="${row.textValue}"/></span>
<br /> <c:out value="${textValue}"/><br/>
<br /></c:forEach></pre>
<br />
<br />Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com1tag:blogger.com,1999:blog-24384544.post-67403219681812821592011-04-05T13:06:00.006+10:002011-10-13T09:30:26.025+11:00IIS7 hiding tomcat webapp error pages<span class="daKeywords">Keywords:</span><br />
IIS IIS7 custom error pages hiding masking tomcat 500 webapp error page jk connector AJP <br />
<br />
<span class="daProblem">Problem:</span><br />
With tomcat integrated into IIS7 using the jk connector error pages from the webapp that have the http-response status set (eg to <code>500</code>) get "replaced" with a generic IIS custom error page:<br />
<pre>
500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed</pre>
<br />
<br />
A quick web-search reveals it's a common issue for ASP.NET developers and the solution is simply to make changes to the ASP.NET application config or in code setting a special <a href="http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors.aspx">HttpResponse.TrySkipIisCustomErrors</a> property(!) ... but what are the options for when the pages are being supplied by an ISAPI redirector/plugin (i.e. the JK connector in this case)? <br />
<br />
<span class="daSolution">Solution:</span><br />
Based on the detailed notes on the IIS Blog (<a href="http://blogs.iis.net/ksingla/archive/2008/02/18/what-to-expect-from-iis7-custom-error-module.aspx">What to expect from IIS7 custom error module</a>) the minimal steps required seem to be the following:<br />
<br />
<h2>
Step 1: create a <code>Web.config</code> file in the root folder of the Web Site</h2>
<br />
This is the Web Site where you've configured the "<span style="font-weight: bold;">jakarta</span>" virtual directory. If it's "<span style="font-style: italic;">Default Web Site</span>" this may be <code>C:\inetpub\wwwroot</code> but check the properties to be sure (Right click Web Site > Manage Web Site > Advanced Settings ... and note the setting for 'Physical Path'). <br />
<br />
<h2>
Step 2: add configuration to the <code>Web.config</code> file</h2>
<br />
<pre><configuration>
<system.webServer>
<httpErrors errorMode="Detailed" existingResponse="Auto" />
</system.webServer>
</configuration></pre>
<br />
<br />
<h2>
Step 3: restart the web site</h2>
<br />
Eg Right click Web Site > Manage Web Site > Restart<br />
<br />
<br />
Be sure to to test this on the local machine (where IIS7 is installed) and from another machine in the network as IIS may give different error-page behaviour for local and 'remote' requests.Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com1tag:blogger.com,1999:blog-24384544.post-81556275336472568072011-03-08T15:15:00.006+11:002011-08-15T20:40:13.557+10:00NTLM from an Axis (SOAP) service client - in 3 steps<span class="daKeywords">Keywords:</span>
<br />NTLM authentication Negotiate Apache axis SOAP IIS Windows Integrated Authentication CommonsHTTPSender NTCredentials
<br />
<br /><span class="daProblem">Problem:</span>
<br />Authenticating a service request with BASIC authentication is (relatively) straightforward:<pre>
<br /> import java.net.URL;
<br /> import org.apache.axis.client.Stub;
<br /> import com.example.service.Example;
<br /> import com.example.service.ExampleServiceLocator;
<br /> import com.example.service.ExampleRequest;
<br /> import com.example.service.ExampleResponse;
<br />
<br /> // get access to the web service
<br /> ExampleServiceLocator locator = new ExampleServiceLocator();
<br /> String serviceURL = "http://server/application/services/example";
<br /> Example example = locator.getexample(new URL(serviceURL));
<br /> // set credentials
<br /><span style="font-weight:bold;"> ((Stub)example).setUsername("myusername");
<br /> ((Stub)example).setPassword("mypassword");</span>
<br />
<br /> // setup request
<br /> ExampleRequest request = new ExampleRequest();
<br /> request.setProperty("SomeProperty");
<br />
<br /> ExampleResponse response = example.example(request);</pre>
<br />
<br />What if the (SOAP) service being called required NTLM authentication (e.g. the service is running in IIS and security is set as "Windows Integrated Authentication")?
<br />
<br /><span class="daSolution">Solution:</span>
<br />The following <span style="font-weight:bold;">three</span> steps are assuming Axis 1.x. The <a href="http://www.nsftools.com/stubby/ApacheAxisClientTips.htm">Apache Axis Client Tips and Tricks</a> is a good reference, in particular for step 2, but also for other "tips".
<br /><h2>Step 1: Add Apache commons-httpclient (3.1) and commons-codec libraries</h2>
<br />Note you must add the <span style="font-style:italic;">commons</span> httpclient jar file and not the (latest/refactored) apache httpclient to the project - or you will get ClassNotFound exceptions.
<br />
<br /><h2>Step 2: Define custom client-config with CommonsHTTPSender</h2>
<br />It's mentioned in the "Tips and Tricks" article mentioned above, but you can either: (a) define a custom <code>client-config.wsdd</code> file in the classpath before <code>axis.jar</code>; (b) edit the generated <code>...ServiceLocator.java</code> generated class and make it override <code>getEngine...</code>; or (c) at runtime simply feed the customised config XML to your <code>...ServiceLocator</code> object.
<br />
<br />I prefer the latter - for example, define a static method with the config XML as a string:<pre>
<br /> protected static org.apache.axis.EngineConfiguration getEngineConfiguration() {
<br /> java.lang.StringBuffer sb = new java.lang.StringBuffer();
<br /> sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
<br /> sb.append("<deployment name=\"defaultClientConfig\"\r\n");
<br /> sb.append("xmlns=\"http://xml.apache.org/axis/wsdd/\"\r\n");
<br /> sb.append("xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">\r\n");
<br /> // sb.append("<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\" />\r\n");
<br /> sb.append("<transport name=\"http\" pivot=\"java:<span style="font-weight:bold;">org.apache.axis.transport.http.CommonsHTTPSender</span>\" />\r\n");
<br /> sb.append("<transport name=\"local\" pivot=\"java:org.apache.axis.transport.local.LocalSender\" />\r\n");
<br /> sb.append("<transport name=\"java\" pivot=\"java:org.apache.axis.transport.java.JavaSender\" />\r\n");
<br /> sb.append("</deployment>\r\n");
<br /> org.apache.axis.configuration.XMLStringProvider config =
<br /> new org.apache.axis.configuration.XMLStringProvider(sb.toString());
<br /> return config;
<br /> } </pre>
<br />
<br />Then the call to the locator would become:<pre>
<br /> // get access to the web service
<br /> ExampleServiceLocator locator = new ExampleServiceLocator(<span style="font-weight:bold;">getEngineConfiguration()</span>);</pre>
<br />
<br /><h2>Step 3: Set the username as <code>DOMAIN\username</code></h2>
<br />Set the username as you did with BASIC authentication but you <span style="font-style:italic;">must</span> ensure is set in the form <code>DOMAIN\username</code> (keeping in mind that if expressing this in java code - as a string - or as a property value in a properties file this would be set as <code>"DOMAIN\\username"</code> - \\ being the escape sequence for \):<pre>
<br /> ((Stub)example).setUsername("<span style="font-weight:bold;">MY_NT_DOMAIN\\</span>myusername");
<br /> ((Stub)example).setPassword("mypassword");</pre>
<br />
<br />With the above 3 steps covered you're using NTLM.
<br />
<br /><span class="daNotes">Notes:</span>
<br />Avoid setting the system property <code>-Djava.ext.dirs</code> as the above relies on the <code>sunjce_provider.jar</code> library which is in JRE_HOME\lib\ext by default. Ext-path problems may give you errors such as:
<br /><code>"Cannot find any provider supporting DES/ECB/NoPadding"</code>
<br />
<br />
<br />Failing to set the username in the form <code>DOMAIN\username</code> will result in the error:<pre>org.apache.commons.httpclient.auth.InvalidCredentialsException:
<br /> Credentials cannot be used for NTLM authentication:
<br /> org.apache.commons.httpclient.UsernamePasswordCredentials
<br /> at org.apache.commons.httpclient.auth.NTLMScheme.authenticate(NTLMScheme.java:332)
<br /> at org.apache.commons.httpclient.HttpMethodDirector.authenticateHost(HttpMethodDirector.java:282)
<br /> at org.apache.commons.httpclient.HttpMethodDirector.authenticate(HttpMethodDirector.java:234)
<br /> at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
<br /> at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
<br /> at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:186)</pre>This is because the format of the username determines the Credentials instance created. With the <code>DOMAIN\...</code> prefix on the username you get an instance of <code>org.apache.commons.httpclient.NTCredentials</code> rather than <code>org.apache.commons.httpclient.UsernamePasswordCredentials</code> - which as the message explains can't be used for NTLM.Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com5tag:blogger.com,1999:blog-24384544.post-19653269125158589312011-01-28T08:41:00.010+11:002011-01-28T09:31:59.599+11:00Is the IBM DB2 UDB service not running? Can't make JDBC Type 4 connections<span class="daKeywords">Keywords:</span><br />IBM DB2 v8 UDB Universal Driver TCP/IP which port windows service JDBC Type 4<br /><br /><span class="daProblem">Problem:</span><br />Attempting to make a <a href="http://www.ibm.com/developerworks/data/library/techarticle/0203zikopoulos/0203zikopoulos.html#N100E7">JDBC Type 4</a> connection (ie pure java talking TCP/IP, no native code) to the DB2 server gives me:<pre><br />com.ibm.db2.jcc.b.SqlException: IO Exception opening socket to server <myservername> on port 50000. <br />The DB2 Server may be down.</pre><br /><br />The DB2 server (running on Windows) is definitely running. In DB2 "Control Center" the "instance" ("DB2" the default name?) is definitely started. Looking at the local TCP ports being listened via <code>netstat -abno</code> there's no <code>50000</code> or anything close. So either the service that accepts the Type-4 JDBC connections (UDB) is not running or it's listening on a different port. How do you check?<br /><br /><span class="daSolution">Solution:</span><br />I couldn't find any mention of this in searching (though I did find "<a href="http://www.ibm.com/developerworks/data/library/techarticle/0301chong/0301chong2.html">DB2 Version 8 Connectivity Cheat Sheet</a>" which is good reference for DB2 generally), but by accident I stumbled on <span style="font-weight:bold;">"Setup communications...</span>" on right clicking the "DB2" instance in DB2 Control Center. From here the rest is straight forward:<ol><br /><li>so, right click the "DB2" instance and select <span style="font-weight:bold;">"Setup communications...</span>"</li><br /><li>check <span style="font-weight:bold;">TCP/IP</span></li><br /><li>click the <span style="font-weight:bold;">Properties</span> button and then just click the <span style="font-weight:bold;">Default</span> button to get default values<ul><br /><li>Note the port number: <code>50000</code> by default</li></ul></li><br /><li>after clicking OK from the Properties and the communications dialog you'll have to restart the instance<ul><br /><li>right click the "DB2" instance and select <span style="font-weight:bold;">Stop</span> and then <span style="font-weight:bold;">Start</span></li></ul><br /></ol><br /><br />Now when you check the open ports via <code>netstat -abno</code> you should hopefully see:<pre><br /> TCP 0.0.0.0:50000 0.0.0.0:0 LISTENING 3012<br /> [db2syscs.exe]</pre><br /><br />To recap the IBM DB2 Universal Driver Type 4 (thin) connection details:<table><tr><td><span style="font-weight:bold;">Driver Class:</span></td><td><code>com.ibm.db2.jcc.DB2Driver</code></td></tr><tr><td><span style="font-weight:bold;">URL:</span></td><td><code>jdbc:db2://<host>[:<port>]/<database_name></code><br/><span style="font-style:italic;">eg:</span><code>jdbc:db2://myservername:50000/MYDATABASE</code></td></tr><tr><td><span style="font-weight:bold;">Driver Class:</span></td><td><code>com.ibm.db2.jcc.DB2Driver</code></td></tr><tr><td><span style="font-weight:bold;">Jar file(s):</span></td><td><code>db2jcc.jar</code> & <code>db2jcc_license_cu.jar</code></td></tr></table>Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0tag:blogger.com,1999:blog-24384544.post-54971631687967221732010-08-18T15:31:00.005+10:002011-10-13T09:31:53.195+11:00Type coercion in JSTL - for sql:param<span class="daKeywords">Keywords:</span><br />
jstl sql integer string type coercion postgres serial operator does not exist: bigint = character varying<br />
<br />
<span class="daProblem">Problem:</span><br />
After upgrading from PostgreSQL 8.0 to 8.4 the following JSTL that queries a table by a passed in "ID":<br />
<pre>
<sql:query var="examples" dataSource="${exampleDataSource}">
select ExampleName as "name"
from ExampleTable
where ExampleId = ?
order by ExampleName ASC
<sql:param value="${param['ID']}"/>
</sql:query></pre>
<br />
Fails with the exception:<br />
<pre>
javax.servlet.jsp.JspException:
select ExampleName as "name"
from ExampleTable
where ExampleId = ?
order by ExampleName ASC
: ERROR: operator does not exist: bigint = character varying
at org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.doEndTag(QueryTagSupport.java:220)
....
Caused by: java.sql.SQLException: ERROR: operator does not exist: bigint = character varying
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1471)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1256)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:175)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:389)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:330)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:240)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93)
at org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.doEndTag(QueryTagSupport.java:215)</pre>
<br />
<br />
Why are there data type errors all of a sudden? ... and how do you fix it?<br />
<br />
<span class="daSolution">Solution:</span><br />
There is normally <a href="http://www.informit.com/articles/article.aspx?p=30946&seqNum=5">Type Coercion</a> for EL expressions but it's a bit vague for <code>sql:param</code>. Ideally it should coerce the param into the type required but this would require knowing the schema & the SQL being executed. So looking at the source for <a href="http://www.docjar.com/html/api/org/apache/taglibs/standard/tag/common/sql/QueryTagSupport.java.html#x295">QueryTagSupport</a> it will just call <code>setObject</code> using the default type that was supplied in the param. <br />
<br />
Contrary to the <a href="http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/sql/param.html"><code>sql:param</code> documentation</a> the value does not have to be a <code>String</code>.<br />
<br />
To get the right type into <code>sql:param</code> use type coercion in EL before the param gets the value. To coerce a <code>String</code> to <code>Integer</code>, you could multiply by 1. For example:<br />
<pre>
<sql:query var="examples" dataSource="${exampleDataSource}">
select ExampleName as "name"
from ExampleTable
where ExampleId = ?
order by ExampleName ASC
<sql:param value="${param['ID']<span style="font-weight: bold;">*1</span>}"/>
</sql:query></pre>
<br />
Or in two steps:<br />
<pre>
<c:set var="exampleId" value="${param['ID']<span style="font-weight: bold;">*1</span>}"/>
<sql:query var="examples" dataSource="${exampleDataSource}">
select ExampleName as "name"
from ExampleTable
where ExampleId = ?
order by ExampleName ASC
<sql:param value="${exampleId}"/>
</sql:query></pre>
<br />
<br />
Why did this come up after a PostgreSQL upgrade? It seems something to do with different handling of the <a href="http://www.postgresql.org/docs/8.1/interactive/datatype.html#DATATYPE-SERIAL"><code>SERIAL</code></a> data type which is now compiled to it's actual representation of <code>integer</code> with <code>sequence</code> rather than leaving it as it's "notational convenience" name. Perhaps the PostgreSQL JDBC will coerce a <code>String</code> to a <code>serial</code> but not an <code>integer</code>? <br />
<br />
It's hard to say the above work around is best practice but it will be harmless for databases that handle coercion at the JDBC level and necessary for those that don't.Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com3tag:blogger.com,1999:blog-24384544.post-45269321693786400662010-06-03T11:29:00.007+10:002011-10-13T09:32:33.412+11:00Stop AXIS output of anonymous complex types in xsi:type<span class="daKeywords">Keywords:</span><br />
apache axis xsi:type anonymous complex type .NET "No type definition found for the type referenced by the attribute 'xsi:type'"<br />
<br />
<span class="daProblem">Problem:</span><br />
The schema definition for a response element may define the complex type "inline" rather than by reference. This is known as an "anonymous type". Eg:<br />
<pre><xs:element name="MyResponse">
<xs:annotation>
<xs:documentation>This is the root element of the Response.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="PropertyOne" type="xs:string" minOccurs="0"/>
<xs:element name="PropertyTwo" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element></pre>
<br />
When axis generates the SOAP response <i>(with the default settings)</i> this includes <code>xsi:type</code> attributes. Eg:<br />
<pre><?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<MyResponse <span style="color: red;">xsi:type="ns1:MyResponse"</span> xmlns="http://example.com/service" xmlns:ns1="http://example.com/service">
...</pre>
<br />
This is accepted by AXIS-generated client code but in .NET (and other schema-validating tools such as XMLSpy) you'll get an error along the lines of <br />
<pre>
No type definition found for the type referenced by the attribute 'xsi:type'='ns1:MyResponse' of element <MyResponse></pre>
<br />
The error inidicates validation is probably doing the right thing with the <code>xsi:type</code> attribute and checking it - there is actually no type with this name, it's anonymous. Can the behavour in AXIS be changed?<br />
<br />
<span class="daSolution">Solution:</span><br />
Thankfully there is a <a href="http://ws.apache.org/axis/java/reference.html#GlobalAxisConfiguration">configuration setting in AXIS</a> to stop this output - <code>sendXsiTypes</code>, which is <code>true</code> by default:<br />
<pre><parameter name="<span style="font-weight: bold;">sendXsiTypes</span>" value="<span style="font-weight: bold;">false</span>"/></pre>
<br />
There are a number of ways to get this setting in there. I'd recommend creating a wsdd deploy file for just the <code>globalConfiguration</code> and deploy this to the AXIS AdminServlet as you would do with the deploy.wsdd definitions for the other service(s). <br />
So an example <code>globalConfig-deploy.wsdd</code>:<br />
<pre>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
...
<parameter name="sendXsiTypes" value="false" />
...
</globalConfiguration>
</deployment></pre>
<br />
You'll find the MyApp/WEB-INF/server-config.wsdd will then be updated and the SOAP excludes this attribute as advertised:<br />
<pre><?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<MyResponse xmlns="http://example.com/service">
...</pre>
<br />
<br />
The alternative to this (if you do want the <code>xsi:type</code> attributes) is to define explicit types for your root response elements. Eg:<br />
<pre><xs:element name="MyResponse" type="MyResponseType">
<xs:annotation>
<xs:documentation>This is the root element of the Response.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:complexType name="MyResponseType">
<xs:annotation>
<xs:documentation>This is the type for the root element of the Response.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PropertyOne" type="xs:string" minOccurs="0"/>
<xs:element name="PropertyTwo" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType></pre>
<br />
The XML from AXIS will then include <code>xsi:type</code> but the value will be correct - referencing a type that does exist. Eg:<br />
<pre><?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<MyResponse xsi:type="<span style="color: red;">ns1:MyResponseType</span>" xmlns="http://example.com/service" xmlns:ns1="http://example.com/service">
...</pre>Kevin Janszhttp://www.blogger.com/profile/18251927796029491111noreply@blogger.com0