tag:blogger.com,1999:blog-51235685314457748342023-10-27T22:02:01.401+02:00Brian SilberbauerBrian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-5123568531445774834.post-24359483534751502232011-01-28T15:34:00.000+02:002011-01-28T15:34:38.049+02:00Writing a WSDL 1.1 Web Service Contract by HandA WSDL document may be confusing at first glance, but is a fairly simple XML document to code by hand once you've understood the concepts. This tutorial will help you writing and understanding the WSDL.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">WSDL Layout</span><br />
The WSDL essentially defines operations grouped as a service, the way these services are called (SOAP etc.) and where the service is hosted.<br />
<br />
We will start by defining the service interface (what operations will be exposed) and the messages used by the operations, then will create the binding and finally the endpoint where the service is hosted.<br />
<br />
The service create will be using the document/literal/wrapped style thats is most common for creating services that are interoperable.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Designing the Service</span><br />
We first need to decide what the service will be: what operations it will be hosting:<br />
<br />
<ul><li>Service Name: <b>Users</b></li>
<li>Operations: </li>
<ul><li><b>addUser</b> - takes user, no return</li>
<li><b>getUser</b> - takes user id, returns user</li>
</ul></ul><div><br />
</div><div><span class="Apple-style-span" style="font-size: large;">Basic WSDL</span></div><div>The root element is '<i>definitions</i>' and we will be declaring all the namespaces on the root element:</div><div><br />
<pre class="brush: xml"><?xml version="1.0"?>
<wsdl:definitions name="Users"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:schema="http://www.example.com/ns/user"
xmlns:tns="http://www.example.com/ns/user/service"
targetNamespace="http://www.example.com/ns/user/service"
>
<wsdl:documentation>
Example Service to demonstrate WSDL authoring.
</wsdl:documentation>
</wsdl:definitions>
</pre><br />
<b>Namespaces</b>:</div><div><ul><li><b>wsdl</b> - the WSDL namespace</li>
<li><b>soap</b> - the SOAP binding</li>
<li><b>schema</b> - our example data schema</li>
<li><b>tns</b> - our namepsace for the WSDL</li>
</ul><div><br />
</div><span class="Apple-style-span" style="font-size: large;">Interface Design</span><br />
Here we will define the service and its operations. We will do this by using the <b>portType</b> element.<br />
<br />
We will call the portType <b>UserEI</b> where 'EI' denotes '<i>Endpoint Interface</i>'. The getUsers operation is a standard request/response type call or IN-OUT Message Exchange Pattern (MEP), the addUser operation we will make an IN-ONLY MEP.<br />
<br />
<pre class="brush: xml"><wsdl:portType name="UserEI">
<wsdl:documentation>User operations</wsdl:documentation>
<wsdl:operation name="getUser">
<wsdl:documentation>Get a User by User ID</wsdl:documentation>
<wsdl:input message="tns:getUser"/>
<wsdl:output message="tns:getUserResponse"/>
</wsdl:operation>
<wsdl:operation name="addUser">
<wsdl:documentation>Add a User</wsdl:documentation>
<wsdl:input message="tns:addUser"/>
</wsdl:operation>
</wsdl:portType>
</pre><br />
Note that the messages (tns:getUser etc..) are not yet defined, see the next section.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Messages</span><br />
Now we define the messages using the '<i>message</i>' element. The messages are mapped to elements defined in the external XSD.<br />
<br />
<pre class="brush: xml"><wsdl:message name="getUser">
<wsdl:part element="schema:getUser" name="parameters"/>
</wsdl:message>
<wsdl:message name="getUserResponse">
<wsdl:part element="schema:getUserResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="addUser">
<wsdl:part element="schema:addUser" name="parameters"/>
</wsdl:message>
</pre><br />
Note that the part refers to the '<i>element</i>' defined in the XSD, not the '<i>type</i>', the part name is '<i>parameters</i>', the element name is the same as the related operation name and there is only one part per message. These are important rules in create '<i>wrapped</i>' style services.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Message Schema</span><br />
As the messages can only have one part/element, this element becomes a 'wrapper' for the data 'parameters' the message contains. I'm not going to go into detail on the XSD schema, as its not the focus of this tutorial. This is how the separate XSD file could look:<br />
<br />
<pre class="brush: xml"><?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msg="http://www.example.com/ns/user"
targetNamespace="http://www.example.com/ns/user"
elementFormDefault="qualified"
attributeFormDefault="qualified"
>
<xsd:element name="getUser" type="msg:getUser"/>
<xsd:element name="getUserResponse" type="msg:getUserResponse"/>
<xsd:element name="addUser" type="msg:addUser"/>
<xsd:complexType name="getUser">
<xsd:sequence>
<xsd:element name="id" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="getUserResponse">
<xsd:sequence>
<xsd:element name="user" type="msg:user"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="addUser">
<xsd:sequence>
<xsd:element name="user" type="msg:user"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="user">
<xsd:sequence>
<xsd:element name="id" type="xsd:string"/>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</pre><pre class="brush: xml"></pre><pre class="brush: xml"><xsd:schema></pre><br />
<span class="Apple-style-span" style="font-size: large;">Import the data definitions</span><br />
The file is imported under the same namespace we declared at the beginning of this tutorial (<i>http://www.example.com/ns/user</i>).<br />
<br />
<pre class="brush: xml"><wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.example.com/ns/user" schemaLocation="userSchema.xsd"/>
</xsd:schema>
</wsdl:types>
</pre><br />
All that left now is to define the binding and where the service is hosted:<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Binding</span><br />
In this example we are going to define SOAP bindings for the service (most common binding). Note that we bind to the interface or 'portType' (tns:UserEI) we defined earlier.<br />
<br />
We are using the '<i>document</i>' style as opposed to '<i>RPC</i>' and the SOAP body is '<i>literal</i>' as opposed to '<i>encoded</i>'.<br />
<br />
<br />
<pre class="brush: xml"><wsdl:binding name="UserBinding" type="tns:UserEI">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getUser">
<soap:operation soapAction="http://www.example.com/ns/user/action/getUser"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="addUser">
<soap:operation soapAction="http://www.example.com/ns/user/action/getUser"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
</wsdl:operation>
</wsdl:binding>
</pre><br />
<span class="Apple-style-span" style="font-size: large;">Endpoint</span><br />
The last thing we need is to specify where the service is being hosted:<br />
<br />
<pre class="brush: xml"><wsdl:service name="UserService">
<wsdl:port binding="tns:UserBinding" name="UserEndpoint">
<soap:address location="http://www.example.com/services/User"/>
</wsdl:port>
</wsdl:service>
</pre><br />
<span class="Apple-style-span" style="font-size: large;">Testing the WSDL</span><br />
When writing something like this by hand, you will make mistakes: in writing the code above I made 4 mistakes, all relating to typos (element names not matching etc..). I checked the WSDL by running Java's wsimport tool, which takes the WSDL as input and generates Java artifacts. Here is the command I ran:<br />
<br />
<pre>wsimport -keep -Xnocompile -s src users.wsdl
</pre><br />
Which generates the Java source in the 'src' directory, does not compile it and keeps the source code.<br />
<br />
You could use a tool like soapui, or an XML editor of your choice.<br />
<br />
<br />
<br />
<br />
</div>Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-27216145092703231792010-03-15T12:31:00.000+02:002010-03-15T12:31:05.804+02:00Dumming Down the User Interface AgainOne of my clients recently asked me to track changes they needed on their eCommerce website I've been maintaining over the last five years. Now, most of you will probably be going 'Hello? Brian has no issue tracking in place for his clients?', but let me defend myself: My client has a low tolerance for learning or being involved in anything that does not impact their business directly.<br />
<br />
I know and understand the advantages of issue tracking and have used and installed a few over the years, almost all opens source (bugzilla, track, scarab et al) and I know the pain of working with any of these tools for the first time: its a big WTF with new terminology and lots of options. Its one of those areas where the domain is simple, but everybody likes it slightly differently: how does an issue start out, is it 'open' is 'started' etc and is it 'high' priority, is it a bug, a feature etc..<br />
<br />
What was ironic about the request is that I had set up issue tracking for them at least a year previously with a system I thought simple enough for them to just start using (they are completely tech literate), but they never used it (they did login though).<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_03tkqSM2ukw/S54BmCBgI2I/AAAAAAAAASA/Q7CasEpbxSc/s1600-h/spreadsheet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="157" src="http://3.bp.blogspot.com/_03tkqSM2ukw/S54BmCBgI2I/AAAAAAAAASA/Q7CasEpbxSc/s320/spreadsheet.png" width="320" /></a></div><br />
I went back to the old stand by: A shared Google Docs Spreadsheet: it is simple and it works and it is better than the 'spreadsheet in a shared folder' pattern, or the 'lets email the spreadsheet around' pattern. We've all been down there before and it is hell. The main problem with spreadsheets is maintaining them for any length of time. They work for month long projects, but anything longer can get chaotic.<br />
<br />
I then spoke with a business friend of mine who is also using a spreadsheet to manage his workers and was complaining about it getting messy and out of state (it might have been a word document). I asked him why he was not using any tools to do this and he said he had tried, but that they were too limiting: he did not care who was updating the system and had no time for confirming tasks etc..<br />
<br />
I was taken aback and forced to think about it, of course he is right. He should not have to adjust the way he works for a tool and the other thing that struck me was that what most of these tools try and enforce should be enforced by other processes rather. If you can't trust your workers to update and maintain a tracking system, you have bigger issues within your business.<br />
<br />
Back to user-interfaces: We need to find some balance between the complex and the simple, between overwhelming the user with options and leaving him to do everything manually.<br />
<br />
Mostly, <i>application development is about automating things people don't want to do</i>. No need complicate it any more than that.<br />
<br />
The next irony in the story is that people love buying complexity! Using Gmail for the first time was a revelation: no complexity, simple interface - less stressful. The interface made me think about interface design in a different way: how can I remove options and how can I streamline the most important tasks.Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-84893484991998833822010-01-19T16:40:00.004+02:002010-01-22T10:08:47.949+02:00JEE6 with Netbeans 6.8 and Glassfish 3<span style=" ;font-family:Arial;font-size:small;"><span style="font-size:13px;"><span style=" ;font-family:'Times New Roman';font-size:medium;"> </span></span></span><br /><span style=" ;font-family:Arial;font-size:small;"></span><br /><span style=" ;font-family:Arial;font-size:small;"></span><br /><span style=" ;font-family:Arial;font-size:small;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">I've been using JEE6 with Netbeans and Glassfish for a while and decided I should update my tutorial <a href="http://blog.gamatam.com/2009/05/creating-jee-application-in-netbeans-65.html">Creating a JEE application in Netbeans 6.5</a> to JEE6.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XGCMDr43I/AAAAAAAAAQ8/gdstv8JyV-s/s1600-h/pigeons.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XGCMDr43I/AAAAAAAAAQ8/gdstv8JyV-s/s320/pigeons.jpg" width="320" /></a><br /></div><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">I'm following a similar loose format and creating a skeleton of an application to show case the various tiers (ORM, business objects and web) and give you an overview of what is possible.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">I also want to demonstrate how easy developing EJB applications has become since the spec came out. I wouldn't be developing with it if it wasn't.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:#444444;">The musical background for today comes from The Willing Mind as a shameless plug ;). Find our music here: </span><a href="http://www.last.fm/music/The+Willing+Mind"><span style="color:#444444;">The Willing Mind on last.fm</span></a><span style="color:#444444;">, </span><a href="http://www.facebook.com/thewillingmind"><span style="color:#444444;">The Willing Mind on Facebook</span></a><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">OK, I've got Netbeans 6.8 loaded, this is what I am running on:<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Product Version: NetBeans IDE 6.8 (Build 200912041610)<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Java: 1.6.0_16; Java HotSpot(TM) 64-Bit Server VM 14.2-b01<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">System: Linux version 2.6.28-17-generic running on amd64; UTF-8; en_ZA (nb)<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">I'm in my testing project group and turning the music on (<span style="color:#444444;">Charls Riff</span>).<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="font-size:x-large;">15:00 - Create new Project</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">File -> New Project -> Java EE -> Enterprise Application -> 'Next'</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Project Name: <span style="color:red;">BooksDemo</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">'Next</span>' again and keep the defaults (Glassfish v3 Domain, Java EE 6 etc)<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">'Finish'</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Three projects will be created for you, the EJB project, the Web Project and the EE project references to EJB and Web project. In my case they were called <span style="color:red;">BooksDemo</span>, <span style="color:red;">BooksDemo-ejb</span> and <span style="color:red;">BooksDemo-war</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="font-size:x-large;">15:04 - Create the Datastore</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b>The Database</b><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">In your '<span style="color:purple;">Services</span>' tag (Ctrl+5) under '<span style="color:purple;">Databases</span>' select Java DB, right click and '<span style="color:purple;">Create Database</span>':<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Database Name: <span style="color:red;">booksdemo</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">User Name: <span style="color:red;">booksdemo</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Password: <span style="color:red;">booksdemo</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:red;"><br /></span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">'OK'</span> and the new Java DB database will be created and start the server if not started.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b>Now the Persistance Unit</b><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Back to your '<span style="color:purple;">Projects</span>' window (Ctrl+1), select the EJB project (<span style="color:red;">BooksDemo-ejb</span>), <span style="color:purple;">right click -> New -> Other -> Persistence -> Persistence Unit -> 'Next'</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">For the Data Source, in the drop down select '<span style="color:purple;">New Data Source..</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">JNDI Name: <span style="color:red;">jdbc/booksdemo</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Database Connection: <span style="color:red;"><select the database you created earlier></span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:red;"><br /></span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">'OK'</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Leave everything else as default and press '<span style="color:purple;">Finish</span>'.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b>The Entity class</b><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">In the projects window right click on the EJB project again and select <span style="color:purple;">'New' -> 'Other' -> Persistence -> Entity Class -> 'Next' </span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Class Name: <span style="color:red;">Book</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Package: <span style="color:red;">com.gamatam.tutorial.book.model</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">'<span style="color:purple;">Finish</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Now add a field to the Book class for the title:<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">Alt+Insert -> Add Property </span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Name: <span style="color:red;">title</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">'<span style="color:purple;">OK</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Thats our data layer finished! (<span style="color:#444444;">listening to 'Lick' by 'The Willing Mind' is it wrong to love your own music so much?</span>)<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="font-size:x-large;">15:23 - Create the Session Bean</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">In the projects window, select the EJB project and <span style="color:purple;">right click again -> New -> Other -> Java EE -> Session Bean -> 'Next'</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">EJB Name: <span style="color:red;">BookService</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Package: <span style="color:red;">com.gamatam.tutorial.book.service</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">'<span style="color:purple;">Finish</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">In the BookService class, <span style="color:purple;">right click -> Persistence -> User Entity Manager</span>, this will add an instance variable for the entity manager.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Now we need the business methods, really easy: <span style="color:purple;">Alt+Insert -> Add Business Method</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Name: <span style="color:red;">getAll</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Return Type: <span style="color:red;">List<Book></span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">'<span style="color:purple;">OK</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;">Alt+Insert -> Add Business Method:</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:purple;"><br /></span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Name: <span style="color:red;">add</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">(Parameters) '<span style="color:purple;">Add</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Name: <span style="color:red;">book</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Type: <span style="color:red;">Book</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color:red;"><br /></span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">'<span style="color:purple;">OK</span>'<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Now to get rid of the squigly lines, or to fix the imports: <span style="color:purple;">Ctrl+Shift+i</span><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Next we need to flesh out the methods a bit.<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"> public List<Book> getAll() {<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"> return em.createQuery("select b from Book b").getResultList();<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"> }<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"> public void add(Book book) {<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"> em.persist(book);<br /></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"> }<br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XCRJcE_gI/AAAAAAAAAQU/kZNUQC-PWLQ/s1600-h/BookService.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XCRJcE_gI/AAAAAAAAAQU/kZNUQC-PWLQ/s320/BookService.png" width="320" /></a><br /></div><div><br /></div><div>OK, that was the business tier, please note there are no longer any interfaces created for the SessionBean!<br /></div><div><br /></div><div><span style="font-size:x-large;">15:36 - The Web</span><br /></div><div><br /></div><div>hmm, thinks a bit as to how to go forward this time..<br /></div><div><br /></div><div>Lets run the application here and do a sanity check: <span style="color:purple;">right click on the BooksDemo main project (probably highlighted) and select 'Run'.</span><br /></div><div><br /></div><div>32 seconds to build, browser coming up and we have 'Hello World!' staring at us, yay. We are looking at the default index.jsp page that was created by Netbeans when we created the project, there is no connection to the datastore or enterprise bean at this stage, but the database should have bean created.<br /></div><div><br /></div><div>Go to the <span style="color:purple;">Services window (Ctrl+5)</span>, under <span style="color:purple;">Databases</span> select the database that we created at the begining of the tutorial, right click and '<span style="color:purple;">Connect</span>', then click to explore the node and select '<span style="color:purple;">BOOKSDEMO</span>', open it and open the '<span style="color:purple;">Table</span>' node.<br /></div><div><br /></div><div>You will see that the '<span style="color:purple;">BOOK</span>' table has been created for you and is made up of an 'ID' column and a 'TITLE' column to mach the properties in the Book entity class.<br /></div><div><br /></div><div><span style="font-size:x-large;">15:46 - Add Book Servlet</span><br /></div><div><br /></div><div>Back to the <span style="color:purple;">project window (Ctrl+1), select the war project (BooksDemo-war), right click -> New -> Other -> Web -> Servlet -> Next</span><br /></div><div><br /></div><div>Class Name: <span style="color:red;">BookAdd</span><br /></div><div>Package: <span style="color:red;">com.gamatam.tutorial.book.web.action</span><br /></div><div><span style="color:purple;">'Next' and 'Finish'</span><br /></div><div><br /></div><div>Note the new 'Webservlet' attribute on the class, this means no more editing of the web.xml for serlvets!<br /></div><div><br /></div><div><span style="color:purple;">Alt+Insert -> Call Enterprise Bean -> select the EJB project (BooksDemo-ejb) and select the BookService -> 'OK'</span><br /></div><div><br /></div><div></div><div>Remove everything from the '<span style="color:purple;">processRequest</span>' method and we will get the book name as a paramter, create a Book object and persist it using the SessionBean:<br /></div><div><br /></div><div> protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {<br /></div><div><div> String title = request.getParameter("title");<br /></div><div> Book book = new Book();<br /></div><div> book.setTitle(title);<br /></div><div> bookservice.add(book);<br /></div><div> response.sendRedirect("index.jsp");<br /></div><div> }<br /></div><div><br /></div></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XDLGh5XSI/AAAAAAAAAQY/aRbEwvBsIFA/s1600-h/BookService.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XDLGh5XSI/AAAAAAAAAQY/aRbEwvBsIFA/s320/BookService.png" width="320" /></a><br /></div><div><br /></div><div>Once you save the servlet, Netbeans should deploy it, so you can test it by trying the following URL:<br /></div><div><br /></div><div><span style="color:orange;">http://localhost:8080/BooksDemo-war/BookAdd?title=test</span><br /></div><div><br /></div><div>You will not see much as the servlet redirects back to the index page, but lets look in the database:<br /></div><div><br /></div><div>In the <span style="color:purple;">Services window (Ctrl+5), right click on the BOOK table and select 'View Data'</span> - you will see a new row inserted with the title 'test'.<br /></div><div><br /></div><div><span style="font-size:x-large;">16:00 - Custom Tag </span><br /></div><div><br /></div><div>Now we will create a custom tag to view all the books:<br /></div><div><br /></div><div>Back to the <span style="color:purple;">project window (Ctrl+1) and right click on the war project -> New- > Other -> Web -> Tag Library Descriptor -> 'Next'</span><br /></div><div><span style="color:purple;"><br /></span><br /></div><div>TLD Name: <span style="color:red;">books</span><br /></div><div><span style="color:red;"><br /></span><br /></div><div>'<span style="color:purple;">Finish</span>'<br /></div><div><br /></div><div><span style="color:purple;">right click on the war project -> New- > Other -> Web -> Tag Handler -> 'Next'</span><br /></div><div><br /></div><div>Class Name: <span style="color:red;">BookTag</span><br /></div><div>Package: <span style="color:red;">com.gamatam.tutorial.book.web.tag</span><br /></div><div>'Next'<br /></div><div>TLD File: <span style="color:red;">WEB-INF/tlds/books.tld</span><br /></div><div>Tag Name: <span style="color:red;">book</span><br /></div><div><span style="color:red;"><br /></span><br /></div><div>'<span style="color:purple;">Finish</span>'<br /></div><div><br /></div><div>Next we add a reference to the BookService EJB and modify the <span style="color:purple;">doTag</span> method so that loops through all the books:<br /></div><div><br /></div><div><div>public class BookTag extends SimpleTagSupport {<br /></div><div> @EJB<br /></div><div> Bookservice bookservice;<br /></div><div><br /></div><div> @Override<br /></div><div> public void doTag() throws JspException, IOException {<br /></div><div> List<Book> books = bookservice.getAll();<br /></div><div> for(Book book: books){<br /></div><div> getJspContext().setAttribute("book", book);<br /></div><div> getJspBody().invoke(null);<br /></div><div> }<br /></div><div> }<br /></div><div>}<br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_03tkqSM2ukw/S1XDyyCYM9I/AAAAAAAAAQc/Nlqhh1hOqzU/s1600-h/BookTag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="143" src="http://1.bp.blogspot.com/_03tkqSM2ukw/S1XDyyCYM9I/AAAAAAAAAQc/Nlqhh1hOqzU/s320/BookTag.png" width="320" /></a><br /></div><div><br /></div><div>Next, in the <span style="color:purple;">index.jsp</span> page we need to first declare the tag library and then use it:<br /></div><div><br /></div><div>Open the <span style="color:purple;">index.jsp</span> page (war project, Web Pages, index.jsp) and add the following:<br /></div><div><br /></div><div><span style="color:red;"><%@taglib uri="/WEB-INF/tlds/books" prefix="b"%></span><br /></div><div><br /></div><div>And in the page body:<br /></div><div><br /></div><div><div> <span style="color:red;"><b:book></span><br /></div><div><span style="color:red;"> ${book.title}</span><br /></div><div><span style="color:red;"> </b:book></span><br /></div><div><br /></div><div>If you reload the page in your browser, you will see a list of books added to the datastore.<br /></div><div><br /></div><div>And lastly, I will add a simple form for adding a book:<br /></div><div><br /></div><div><span style="color:red;"><form action="BookAdd"><input name="title"><input type="submit"></form></span><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XEOygSPOI/AAAAAAAAAQg/bDWn90rgEjA/s1600-h/index.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="140" src="http://4.bp.blogspot.com/_03tkqSM2ukw/S1XEOygSPOI/AAAAAAAAAQg/bDWn90rgEjA/s320/index.png" width="320" /></a><br /></div><div><br /></div><div>And at 16:17, thats a wrap!<br /></div><div><br /></div><div><br /></div></div></div><div><div>I'll leave it as an exercise for you to 'dolly' it up.<br /></div></div><div><br /></div></span>Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-63192370199101417872009-11-04T17:05:00.000+02:002009-11-04T17:05:49.252+02:00JDBC Realm Setup with Glassfish v3 (build 70) and Netbeans 6.8 (beta) JEE6As I am about to undertake this and I can't find instructions using the glassfish GUI admin, I might as well blog it:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_03tkqSM2ukw/SvGX_W6EPWI/AAAAAAAAAO0/h5P-5t23KS0/s1600-h/02102009198sm.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/_03tkqSM2ukw/SvGX_W6EPWI/AAAAAAAAAO0/h5P-5t23KS0/s320/02102009198sm.jpg" /></a><br />
</div><br />
<span style="font-size: x-large;">Database</span><br />
<b>Create Database</b><br />
I'm going to use the Derby/JavaDB database that came with Netbeans:<br />
<br />
Click on the 'services' tab in Netbeans<br />
Right click on JavaDB under Databases and select 'Create Database..'<br />
Input details for the database, I used 'security' for database name , username and password (ironically).<br />
<br />
<b>Create Connection Pool for Database</b><br />
Then in the Glassfish admin panel:<br />
Resources->JDBC->Connection Pools, select 'New'<br />
Name: security<br />
Resource Type: javax.sql.DataSource<br />
Database Vendor: JavaDB<br />
<next><br />
Scroll down to additional properties:<br />
DatabaseName: security<br />
User: security<br />
Password: security<br />
ServerName: localhost<br />
<br />
NB! Delete all other properties.<br />
<br />
<save><br />
then try 'ping' it<br />
<br />
make sure your database is up and running, compare properties to other loaded connection pools..<br />
<br />
<b>Create JDBC Resource</b><br />
In the Glassfish admin panel:<br />
Resources->JDBC->JDBC resources, select 'new'<br />
JNDI Name: jdbc/security<br />
Pool Name: security<br />
<OK><br />
<br />
<b>Create Tables</b><br />
In Netbeans 'Services' tab:<br />
Database->jdbc:derby://localhost:1527/security, right click and select 'Execute Command'<br />
<br />
create table usertable (<br />
username varchar(128) NOT NULL CONSTRAINT USER_PK PRIMARY KEY ,<br />
password varchar(128) NOT NULL<br />
);<br />
and<br />
<br />
create table grouptable(<br />
username varchar(128) NOT NULL,<br />
groupid varchar(128) NOT NULL,<br />
CONSTRAINT GROUP_PK PRIMARY KEY(username, groupid),<br />
CONSTRAINT USER_FK FOREIGN KEY(username) REFERENCES usertable(username)<br />
ON DELETE CASCADE ON UPDATE RESTRICT<br />
);<br />
and populate:<br />
<br />
insert into usertable(username,password) values ('admin', '21232f297a57a5a743894a0e4a801fc3');<br />
insert into grouptable(username,groupid) values ('admin', 'USER');<br />
insert into grouptable(username,groupid) values ('admin', 'ADMIN');<br />
<br />
<br />
scripts modified slightly from http://blogs.sun.com/foo/resource/createschema.sql from the article http://blogs.sun.com/foo/entry/mort_learns_jdbc_realm_authentication<br />
<br />
Which is pretty much what I am doing..<br />
<br />
<span style="font-size: x-large;">Realm</span><br />
<b>Create New</b><br />
In the Glassfish admin panel:<br />
Configuration->Security->Realm, select <new><br />
Name: security<br />
Class Name: the one with 'jdbc' in it<br />
<br />
JAAS Context: jdbcRealm<br />
JNDI: jdbc/security<br />
User Table: usertable<br />
User Name Column: username<br />
Password Column: password<br />
Group Table: grouptable<br />
Group Name Column: groupid<br />
Digest Algorithm: MD5<br />
<OK><br />
<br />
time to test..<br />
<br />
<span style="font-size: x-large;">Web Config</span><br />
<b>Roll Mapping</b><br />
In Netbeans in the projects tab:<br />
<your war project>->Configuration Files->sun-web.xml and open it<br />
click on <security><br />
<Add Security Role Mapping><br />
Security Role Name: USER<br />
<Add Group><br />
Group Name: USER<br />
<br />
and do the same for the admin role/group<br />
<br />
<b>web.xml</b><br />
As I am using JEE 6, I have had no need for the web.xml file as yet, so now I need to create it:<br />
right click on the war project<br />
new->other->Web->Standard Deployment Descriptor<br />
<br />
now edit it:<br />
select the 'Security' button/tab<br />
under 'Login Configuration' select Basic<br />
Realm Name: security<br />
<br />
then under Security Roles <Add..><br />
Role Name: USER<br />
do the same for ADMIM role<br />
<br />
Now <Add Security Constraint><br />
Display Name: Test Constraint<br />
<br />
Web Resource Collection <Add..><br />
Resource Name: test<br />
URL Pattern(s): /test/*<br />
<OK><br />
<br />
tick 'Enable Authentication Constraint'<br />
Role Name(s): USER<br />
<br />
and save..<br />
<br />
create a directory 'test' with a jsp file in it and try access it..<br />
<br />
Worked for me, yay me!Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-36050968400906360902009-05-22T11:27:00.002+02:002009-05-22T11:34:54.819+02:00Creating a MySQL Database on an External Drive - Things I will forget [002]The harddrive on my laptop is filling up and I have a client who's database runs into the gigs (per dataset). So I created a MySQL database on an external harddrive a while ago, but now need to do it again (the harddrive is flaky) and have forgotten how to do it. I seem to be looking in the wrong places, so maybe if I write this blog other people searching for the same thing will find it and be able to use it. I will be able to do it next time without searching too!<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_03tkqSM2ukw/ShZuWxssEyI/AAAAAAAAALc/FSnQ137rWmQ/s1600-h/mysql.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/_03tkqSM2ukw/ShZuWxssEyI/AAAAAAAAALc/FSnQ137rWmQ/s320/mysql.jpg" /></a></div><br />
Well, its actually quite easy. I first tried to create a separate configuration file like I did the previous occasion, but this means not being able to store the config file on the disk: mysql requires that the config file not be world writeable, but by default the external hardrive is mounted with all files world read/writeable. So rather than mess about with the fstab and change the way it is mounted, I opted for specifying the options on the command line.<br />
<br />
So this is what I had to do:<br />
<br />
<br />
First I created I directory where the MySQL database would reside, all further commands are run from that directory.<br />
<br />
I then created a data directory store the databases:<br />
<br />
<div style="color: #073763;">mkdir data</div><br />
I the ran <span style="color: #660000;">mysql_install_db</span> to initialize the MySQL database tables:<br />
<div style="color: #073763;"></div><div style="color: #073763;">mysql_install_db --ldata=data</div><br />
Then I could start the database (remember to shutdown your other mysql database if it is running, else specify a different port for this databse to run on): <br />
<br />
<div style="color: #073763;">mysqld --pid-file=./mysqld.pid --socket=./mysqld.sock --datadir=./data</div><br />
I put this into a '<span style="color: #660000;">start.sh</span>' script.<br />
<br />
The socket file will be created in the data directory (<span style="color: #660000;">data/mysqld.sock</span>. <br />
You can then connect to the database like this: <br />
<br />
<div style="color: #073763;">mysql --user=root --socket=./data/mysqld.sock</div><br />
If you want access to the MYSQL tables use <span style="color: #660000;">--user=root</span>, else create your own users etc. If you want to use the <span style="color: #660000;">MySWL Administrator</span> and <span style="color: #660000;">MySQL Query Browser</span> graphical front ends, make sure you specify the socket file:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_03tkqSM2ukw/ShZvGL0B5nI/AAAAAAAAALk/VGTbAL48_B4/s1600-h/msql02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/_03tkqSM2ukw/ShZvGL0B5nI/AAAAAAAAALk/VGTbAL48_B4/s320/msql02.png" /></a></div><br />
<br />
Shutdown the database using the following command:<br />
<br />
<div style="color: #073763;">sudo mysqladmin shutdown -S ./data/mysqld.sock</div><br />
It bothers me that I have to shut it down using sudo, I'll look for a work around when it starts to really irritate me.<br />
<br />
Now to wait for the 8 Gig of data to load.<br />
<br />
<div style="color: #999999;">On a side note: I don't think <i>Acid Mothers Temple</i> is the best band to listen to while programming, my brother might disagree..<br />
<br />
<span style="font-size: x-small;"><span style="color: #cc0000;"><<Blog as memory>></span></span></div>Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-34394051896309634142009-05-06T12:34:00.003+02:002009-05-22T09:00:02.426+02:00Creating a JEE application in Netbeans 6.5<a href="http://2.bp.blogspot.com/_03tkqSM2ukw/SgFqtumsB3I/AAAAAAAAAK8/a0ezut4EvaY/s1600-h/owl.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img src="http://2.bp.blogspot.com/_03tkqSM2ukw/SgFqtumsB3I/AAAAAAAAAK8/a0ezut4EvaY/s200/owl.jpg" border="0" /></a>This is the first thing I do when giving a course on JEE: I open up Netbeans, create a JEE project, create a JavaDB database, create a JPA persistance unit, create an entity bean, create a session bean, create a servlet, create a JSP page and create a cutsom tag (all associated with the entity bean created).<br /><br />This is a great help to the students as it gives them the overview of what we will be working with and shows them how quick and easy it is to create a JEE application in Netbeans - It takes the complexity fear out of them (to a certain extent).<br /><br />I thought it would be a great help if this were available as a blog for others to follow. Comments will be most welcome, but not that this is pretty much off the cuff and bares no relevence to a real application.<br /><br />I'll provide a time line to give you an idea of speed, my slow laptop and making it up as I go along should handicap my normal coding dexterity :)<br /><br /><b>10:51</b> - music selection, hmm, Black Keys, Brian Eno and David Byrne, Cake.<br /><div style="color: rgb(153, 153, 153);"></div><span style="color: rgb(153, 153, 153);">Ahh, Thickfreakness!</span><br /><br /><br /><span style="font-size:large;">10:55 - Project creation</span><br /><div style="text-align: left;"></div><div class="separator" style="clear: both; text-align: center;"></div><div style="color: rgb(19, 79, 92);">New Project -> Java EE -> Enterprise Application </div>I'm calling it <span style="color: rgb(153, 0, 0);">BooksDemo</span><br />Using the defaults: Glassfish V2, Java EE 5, Create EJB Module, Create Web Application Module<br /><br />This will create three projects - <span style="color: rgb(153, 0, 0);">BooksDemo</span> 'containing' <span style="color: rgb(153, 0, 0);">BooksDemo-ejb</span> and <span style="color: rgb(153, 0, 0);">BooksDemo-war</span><br /><br /><span style="font-size:large;">11:02 - Create the Datastore</span><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_03tkqSM2ukw/SgFRwtuD-WI/AAAAAAAAAKc/f6M1nmFAe-U/s1600-h/jee01.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img src="http://1.bp.blogspot.com/_03tkqSM2ukw/SgFRwtuD-WI/AAAAAAAAAKc/f6M1nmFAe-U/s200/jee01.png" border="0" /></a></div>Under Databases in your '<span style="color: rgb(19, 79, 92);">services</span>' tag, right click on '<span style="color: rgb(19, 79, 92);">Java DB</span>' and select '<span style="color: rgb(19, 79, 92);">Create Database</span>' and create a database called '<span style="color: rgb(153, 0, 0);">BooksDemo</span>' with <span style="color: rgb(19, 79, 92);">username</span> and <span style="color: rgb(19, 79, 92);">password</span> set to '<span style="color: rgb(153, 0, 0);">books</span>' (I've found it doesn't work so well to not have username and password - go figure).<br /><br />The creation will also start the database, if you go back to the services tab, you will be able to open and view the database.<br /><br />Back to the project tab: select '<span style="color: rgb(153, 0, 0);">BooksDemo-ejb</span>', <span style="color: rgb(19, 79, 92);">right click -> new -> other -> Persistance -> Persistence Unit - > Next</span><br />I use the default unit name (<span style="color: rgb(153, 0, 0);">BooksDemo-ejbPU</span>) and for datasource select '<span style="color: rgb(19, 79, 92);">New Data Source</span>' at the bottom of the dropdown. Then select the <span style="color: rgb(153, 0, 0);">BooksDemo</span> database you created earlier and make the JNDI name '<span style="color: rgb(153, 0, 0);">jdbc/booksDemo</span>', leave the rest as default and finish.<br /><br />Now for the Entity Object:<br />Back to the project tab: select '<span style="color: rgb(153, 0, 0);">BooksDemo-ejb</span>', <span style="color: rgb(19, 79, 92);">right click -> new -> other -> Persistance -> Entity Class -> Next</span><br /><br />Classname '<span style="color: rgb(153, 0, 0);">Book</span>', package '<span style="color: rgb(153, 0, 0);">com.example.book.model</span>' the rest default and <span style="color: rgb(19, 79, 92);">finish</span>.<br /><br />In the <span style="color: rgb(153, 0, 0);">Book</span> class, create a new field '<span style="color: rgb(153, 0, 0);">name</span>' as a String field: <span style="color: rgb(19, 79, 92);"><alt>INSERT -> Add Property</span>: make the <span style="color: rgb(19, 79, 92);">name</span> '<span style="color: rgb(153, 0, 0);">name</span>' and select OK.<br /><br /><span style="font-size:large;">11:15 - Create the SessionBean</span><br /><br /><div style="color: rgb(153, 153, 153);">(Brian Eno is a genius)</div><br /><a href="http://2.bp.blogspot.com/_03tkqSM2ukw/SgFYLZhhEII/AAAAAAAAAKk/5fOxbr05LnA/s1600-h/jee02.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img src="http://2.bp.blogspot.com/_03tkqSM2ukw/SgFYLZhhEII/AAAAAAAAAKk/5fOxbr05LnA/s200/jee02.png" border="0" /></a>In the project tab: select '<span style="color: rgb(153, 0, 0);">BooksDemo-ejb</span>', <span style="color: rgb(19, 79, 92);">right click -> new -> other ->Java EE -> Session Bean -> Next</span><br /><br />Call it '<span style="color: rgb(153, 0, 0);">BookService</span>', package '<span style="color: rgb(153, 0, 0);">com.example.book.service</span>', the rest default.<br /><br />Now we are going to create two 'business' methods: getAll and add for retrieving all books and add a book to the datastore.<br /><br /><span style="color: rgb(19, 79, 92);"><ALT>INSERT -> Add Business Method</span> with name '<span style="color: rgb(153, 0, 0);">getAll</span>' with return type '<span style="color: rgb(153, 0, 0);">List<Book></span>'<br /><br /><span style="color: rgb(19, 79, 92);"><ALT>INSERT -> Add Business Method</span> with name '<span style="color: rgb(153, 0, 0);">add</span>' and add a parameters called '<span style="color: rgb(153, 0, 0);">book</span>' of type '<span style="color: rgb(153, 0, 0);">Book</span>'.<br /><br />Next fix the imports - <span style="color: rgb(19, 79, 92);"><CTRL>-<SHIFT>-I</span> (in the interface as well)<br /><br /><br />Next we need a handle on the persistance unit: Right click in the <span style="color: rgb(19, 79, 92);">BookServiceBean -> Persistence -> Use Entity Manager</span><br /><br />You will now have something like the diagram above.<br /><br />Now we need to use the EntityManager to store and retrieve the books: for the getAll method:<br /><br /><span style="color: rgb(153, 0, 0);">return em.createQuery("select b from Book b").getResultList();</span><br /><br />for the add method:<br /><br /><div style="color: rgb(153, 0, 0);">em.persist(book);</div><br /><span style="font-size:large;">11:31 - The Web</span><br /><br />We are going to edit the index.jsp ading a form to add a book and retrieve a list of books.<br /><br />hmm, we need a Servlet to act as the action storing the book first:<br /><br />On the '<span style="color: rgb(153, 0, 0);">BooksDemo-war</span>' (note its 'war', dammit) <span style="color: rgb(19, 79, 92);">right click -> new -> other -> Web -> Servlet -> Next</span><br /><br />Class Name: '<span style="color: rgb(153, 0, 0);">BookAdd</span>'<br />package: '<span style="color: rgb(153, 0, 0);">com.example.book.web.action</span>'<br /><br />the rest is default, click 'next' and 'finish' (note that the servlet will be called using <span style="color: rgb(153, 0, 0);">'/BookAdd</span>' in the URL.<br /><br />Add the SessionBean by <span style="color: rgb(19, 79, 92);"><ALT>-INSERT (in the servlet class) -> Call Enterprise Bean</span> and select the <span style="color: rgb(153, 0, 0);">BookServiceBean</span> and OK.<br /><br />Edit the 'processRequest' method, take everything out and replace it with the following:<br /><br /> <span style="color: rgb(153, 0, 0);">Book book = new Book();</span><br /><span style="color: rgb(153, 0, 0);"> book.setName(request.getParameter("name"));</span><br /><span style="color: rgb(153, 0, 0);"> bookServiceBean.add(book);</span><br /><span style="color: rgb(153, 0, 0);"> response.sendRedirect("index.jsp");</span><br /><br />We can see if we are on the right track so far: in the project tab, select the '<span style="color: rgb(153, 0, 0);">BooksDemo</span>' projec, right click and '<span style="color: rgb(19, 79, 92);">Run</span>'<br /><br />This took me 1 min 6 sec..<br /><br />You should see 'Hello World!' in your browser, this is the index.jsp we haven't edited yet.<br /><br />Add '<span style="color: rgb(56, 118, 29);">BookAdd?name=test</span>' to the URL in the browser navigation thingy, you should be redirected to the index page, so you will not see anything of value in the browser. this is good. if you see stack traces, bummer.<br /><br /><span style="color: rgb(19, 79, 92);">Go to the Services tab, select Database, select the BooksDemo database, Tables, Book -> right click -> View Data</span>, you should see a record in the table with the name 'test', Hurrah!<br /><br /><span style="font-size:large;">11:50 - The index.jsp</span><br /><br /><br /><br /><span style="color: rgb(19, 79, 92);">Under 'Web Pages' in the 'BooksDemo-war</span>' project you will find the index.jsp page, open it and add the following code after '<h1>Hello World!</h1>':<br /><br /><span style="color: rgb(153, 0, 0);"> <form method="post" action="BookAdd"></span><br /><span style="color: rgb(153, 0, 0);"> <input name="name"/></span><br /><span style="color: rgb(153, 0, 0);"> <button type="submit">add</button></span><br /><span style="color: rgb(153, 0, 0);"> </form></span><br /><br />Save it, reload your browser and you should see a form with one input field and an 'add' button, enter a name for a new book and press 'add'. Check that you have a new record in the database.<br /><br /><br /><span style="font-size:large;">Custom Tag</span><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_03tkqSM2ukw/SgFhSHS9n3I/AAAAAAAAAKs/7tcEVCCUoEI/s1600-h/jee03.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img src="http://1.bp.blogspot.com/_03tkqSM2ukw/SgFhSHS9n3I/AAAAAAAAAKs/7tcEVCCUoEI/s200/jee03.png" border="0" /></a></div>On the '<span style="color: rgb(153, 0, 0);">BooksDemo-war</span>' <span style="color: rgb(19, 79, 92);">right click -> new -> other -> Web -> Tag Library Descriptor -> next</span><br /><br />TLD Name: <span style="color: rgb(153, 0, 0);">books</span><br />default for the rest and click 'finish'<br /><div style="text-align: right;"></div>On the '<span style="color: rgb(153, 0, 0);">BooksDemo-war</span>' <span style="color: rgb(19, 79, 92);">right click -> new -> other -> Web ->Tag Handler -> Next</span><br /><br />Class Name: <span style="color: rgb(153, 0, 0);">BookTag</span><br />Package: <span style="color: rgb(153, 0, 0);">com.example.book.web.tag</span><br />default for the rest and click 'Next'<br /><br />TLD File: <span style="color: rgb(153, 0, 0);">WEB-INF/tlds/books.tld</span> (browse to it)<br />Tag Name: <span style="color: rgb(153, 0, 0);">book</span><br />default for the rest and click 'finish'<br /><br />In the <span style="color: rgb(153, 0, 0);">BookTag</span> class, <span style="color: rgb(19, 79, 92);"><ALT>-INSERT -> Call Enterprise Bean and select BookServiceBean</span>.<br /><br />Next, remove everything from the 'doTag' method and add the following:<br /><br /><span style="color: rgb(153, 0, 0);"> BookServiceLocal bookServiceBean = lookupBookServiceBean();</span><br /><span style="color: rgb(153, 0, 0);"> List<Book> books = bookServiceBean.getAll();</span><br /><span style="color: rgb(153, 0, 0);"> for(Book book: books){</span><br /><span style="color: rgb(153, 0, 0);"> getJspContext().setAttribute("book", book);</span><br /><span style="color: rgb(153, 0, 0);"> getJspBody().invoke(null);</span><br /><span style="color: rgb(153, 0, 0);"> }</span><br /><br />You will also need to throw the IOException.<br /><br />Back to index.jsp,at the top of the page add the following directive:<br /><br />under the '<%@page' directive,<br /><div style="color: rgb(153, 0, 0);"><%@taglib uri="/WEB-INF/tlds/books" prefix="b"%></div><br />Note: you can <span style="color: rgb(19, 79, 92);"><CTRL>-SPACE</span> to auto complete the uri.<br /><br />(sheep go to heaven, goats go to hell)<br /><br />Then add the following under the form:<br /><br /> <span style="color: rgb(153, 0, 0);"> <hr/></span><br /><span style="color: rgb(153, 0, 0);"> <table></span><br /><span style="color: rgb(153, 0, 0);"> <tr></span><br /><span style="color: rgb(153, 0, 0);"> <th>name</th></span><br /><span style="color: rgb(153, 0, 0);"> </tr></span><br /><span style="color: rgb(153, 0, 0);"> <b:book></span><br /><span style="color: rgb(153, 0, 0);"> <tr></span><br /><span style="color: rgb(153, 0, 0);"> <td>${book.name}</td></span><br /><span style="color: rgb(153, 0, 0);"> </tr></span><br /><span style="color: rgb(153, 0, 0);"> </b:book></span><br /><span style="color: rgb(153, 0, 0);"> </table></span><br /><br /><br />If you reload your browser you should have a list of your book under the form:<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_03tkqSM2ukw/SgFhsvDJa5I/AAAAAAAAAK0/22HmswgeGJI/s1600-h/jee04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img src="http://3.bp.blogspot.com/_03tkqSM2ukw/SgFhsvDJa5I/AAAAAAAAAK0/22HmswgeGJI/s320/jee04.png" border="0" /></a> </div><div class="separator" style="clear: both; text-align: left;"> <span style="font-size:large;">And at 12:09, thats a wrap.</span></div><div class="separator" style="clear: both; text-align: left;"></div><div class="separator" style="clear: both; text-align: left;"></div>At just under two hours, I don't think its that bad for getting a trivial application up and running (bear in mind I did not prepare for this, so some time was spent thinking each step through), if you had to do it by hand it would be more of a headache. Netbeans adds a lot of value to creating these applications.<br /><br />The project seems to slow down once we reach the web side of things, but maybe one day we'll have a better way of creating web applications :)Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-66275553026423250712009-04-24T11:28:00.001+02:002009-04-24T11:34:23.272+02:00Real world GAEJ ApplicationOK, this is a very sketchy view of developing a first time application with GAEJ. It is a rewrite (not a port) of an application I wrote a while back in Java using Spring and JPA. The application is a timetracker recording time I spend on various client projects, I will publish the URL once I've cleaned up a few things and I want to add GWT to the front end.<br />
<br />
This is my experience, warts and all, maybe it will help others. I'm using the eclipse plugin for development.<br />
<br />
<span style="font-size: large;">Persistance</span><br />
<br />
In my previous hack, I used JDO to see what it was like, I didn't much like it and decided to move back to JPA. I found JDO quite verbouse to use and especially did not like the way you have to declsre parameters for queries.<br />
<br />
The first step was to create the persistance.xml file, as the eclipse plugin only provides the jdo configuration as default. Its easy enough, put it in the same place as your jdoconfig.xml file (in the META-INF directory).<br />
<br />
You will need to identify the Entity classes by specifying them in the persistenace.xml file using the <class> tag.<br />
<br />
See <a href="http://code.google.com/appengine/docs/java/datastore/usingjpa.html#Setting_Up_JPA">Setting Up JPA</a> in the docs. Hmm, the line<br />
EntityManager em = EMF.get().getEntityManager();<br />
should be changed to:<br />
EntityManager em = EMF.get()createEntityManager();<br />
<br />
Wow! Changed the JDO persisted class to a JPA entity class by changing the annotations and implementing Serializable and.. it work!!<br />
<br />
<br />
<br />
<span style="font-size: large;">Security</span><br />
<br />
Edit the deployment descriptor (web.xml to you and me) and include the <br />
<b>security-constraint</b> tag. There is an example in the docs called <a href="http://code.google.com/appengine/docs/java/config/webxml.html#Security_and_Authentication">Security and Authentication</a>.<br />
<br />
See <a href="http://code.google.com/appengine/docs/java/users/overview.html">Google Accounts Java API Overview</a> in the docs.<br />
<br />
OK, then how does one access the user principal using EL in a JSP page?<br />
<br />
<br />
<br />
Looking at the user principal I see it is implemented as: <b>com.google.apphosting.utils.jetty.</b><br />
<b>AppEngineAuthentication$AppEnginePrincipal</b><br />
<br />
<br />
<br />
<b>UserServiceFactory.getUserService().getCurrentUser()</b> which return a <b>com.google.appengine.api.users.User</b> object. There mus be some relationship to <b>AppEnginePrincipal</b>, but its not via inheritance. <br />
<br />
Some digging around and I see <b>AppEnginePrincipal</b> holds an instance of <b>User</b>, so I can do this in JSP:<br />
<br />
${pageContext.request.userPrincipal.user.email}<br />
or<br />
${pageContext.request.userPrincipal.user.nickname}<br />
apart from:<br />
${pageContext.request.userPrincipal.name}<br />
<br />
(of course, once the user is logged in)<br />
<br />
Any resources specified in a security-constraint will cause a redirect to the google login page. Any User specified as a developer on the application will have admin role, not sure what role everybody else gets or how to get more roles.<br />
<br />
<span style="font-size: large;">The Turn Around </span><br />
<br />
Under the persistance section I mentioned moving from JDO to JPA, I really don't like JDO from a usablility point of few, the stench is too high - I don't want to be that aware of my datastore. <br />
<br />
But now I find myself going back to JDO for a number of reasons:<br />
<ol><li>Not enough documentation on GAEJ about using JPA</li>
<li>The JPA implementation is basically JDO under the hood and I get the feeling not everything translates well.<br />
</li>
<li>JDO is simpler for storing objects outside your domain (the User object springs to mind)</li>
<li>There is a general ".. I don't know, use JDO.." attitude on the mailing list</li>
<li>I plan to use GWT in the project and there are serious issues regarding serializing Entities - <a href="http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/3c768d8d33bfb1dc">GWT-RPC broken in GAE/J</a>.</li>
</ol>bugger, I really don't want to do this, humph. <br />
<br />
The DataNucleus Enhancer is starting to T me off, keeps on popping up in the console after you save any class in your project, perhaps it should only be kicked off when saving persistant objects or not output unless on error.<br />
<br />
Ah, got it: under your project properties -> google -> appengine -> ORM you can specify the specific file/ packages you want enhanced. Nice.<br />
<br />
And we are back with JDO. The data hasn't changed, the same data was accessed by JDO, then JPA, then back to JDO without issue.<br />
<br />
=================================<br />
Then there is a gap where I modify my J2ME MIDlet, faf around with getting data from the phone and add a domain to my application and run out of bandwidth. This is not a happy period.<br />
=================================<br />
<br />
Implicit params in the JDO queries will be supported in the next release. Meh<br />
<br />
<span style="font-size: large;">The other 'Duh' drops</span> <br />
<br />
Spent a lot of time trying to figure out relationships and how to implement it with GAE. Did some more reading and recommend these articles: <a href="http://www.geekinasuit.com/2009/04/re-thinking-object-relational-mapping.html">Re-thinking Object-Relational Mapping in a Distributed Key-Store world</a> and <a href="http://highscalability.com/how-i-learned-stop-worrying-and-love-using-lot-disk-space-scale">How I Learned to Stop Worrying and Love Using a Lot of Disk Space to Scale</a>. I've simplified my initial design dramatically and geared it towards my end goals and a (gasp!) de-normalized the design.<br />
<br />
The thing that bothers me most is using JDO/JPA for something like this.I'm going to have a look at the lower level APIs and see if they make more sense (at some stage)<br />
<br />
It would be nice to include a restart button for the local web host within eclipse.<br />
<br />
<span style="font-size: large;">Sessions</span><br />
<br />
Session support is not enabled in appengine-web.xml by default. To enable sessions, put <sessions-enabled>true</sessions-enabled> in that file.<br />
<br />
I've read somewhere that read only session attributes are supported out the box, I guess that is why you have access to the UserPrincipal. <br />
<br />
And while I'm on session:: it seems objects stored in the session must be serializable, not obvious under the test server, but going live will throw exceptions. <br />
<br />
And you can view your applications sessions via the data viewer in the application administrator.<br />
<br />
<br />
I finally understand why a lot of people are against pure servlet/JSP/taghandler development, they were probably using eclipse. A NetBeans GAEJ module would be nice.<br />
<br />
<span style="font-size: large;">Conclusion of Sorts</span><br />
<br />
The major headache is around data access at the moment. Working with BigTable requires a mind change if your are used to relational databases.Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-3004515256472666022009-04-10T15:08:00.000+02:002009-04-10T15:08:02.765+02:00Google Appengine Java Test RideTime to climb on the appengine-java-blog train.<br />
<br />
<b>9:45</b> OK, Bootsy Collins 'If 6 was 9' playing, check.<br />
<br />
I've created a an app using appengine with python and as much as writting in python is fun, I don't like the maintenance aspect of it (trying to remember what methods classes had without looking it up again etc).<br />
<br />
I really like the idea of appengine especially the ease of use in deploying and versioning your application, but especially the zero cost to try aspect. I'm dying to try amazon's service, but I can't try it without entering my credit card details and I don't have one at the moment.<br />
<br />
So I've been looking forward to writing for appengine in java. Here is my first experience with it I timestamped to give you an idea of the time it takes to create and app. I've been programming in Java since 1995 and Servlets since 2000, so your experience may vary ;)<br />
<br />
The <i>kids are watching Asterix in the study, bit distracting but I have headphones, hence the musical references<br />
</i><br />
<br />
<b>10:02</b> So, eclipse plugin loaded, lets create a servlet and send it live.<br />
<br />
<b>10:04</b> Project created without GWT, creates a default servlet, bleh.<br />
<br />
<b>10:05</b> Simple single button project publishing, must create new application on appengine first.<br />
<br />
The deploy dialog doesn't display application setting by default, need to open 'App Engine project settings..', not quite intuitive. Weird email completion too (got it wrong first time).<br />
<br />
<b>10:09</b> Up and running! Not bad, under ten minutes to create a new application and send it live, pretty painless.<br />
<br />
Next: index.jsp -> link to servlet -> forward to index.jsp<br />
<br />
hmm, creating a servlet using the wizard doesn't work, needs a web project and I can't enter one. Oh well, back to creating by hand, will look into that later..<br />
<br />
<i>rrr, prefer netbeans</i><br />
<br />
<b>10:19</b> editing web.xml -> added TestServlet, changed welcome file to index.jsp<br />
<br />
<b>10:21</b> Re-deploying the app I have to re-enter password, that could be improved.<br />
<br />
<b>10:22</b> Tested and working, yay!<br />
<br />
Next lets try persisting some data (as soon as 'Maggot Brain' is finish)<br />
<br />
JDO or JPA: I've used JDO long time we go, been using JPA since it came out, but there seems to be more documentation for JDO on the appengine site and I can't resist trying unfamiliar technology, so JDO it is.<br />
<br />
Let me try vertical development and implement an object first without relationships and do some basic CRUD. later (10:28)<br />
<br />
<b>10:30</b> Going to read the docs about created JPA Entities in eclipse..<br />
<br />
Once I've added the annotaions to the class, saving it triggers the enhancer as reported in the output: 'DataNucleus Enhancer completed with success', cool.<br />
<br />
<b>10:38</b> Created the persistent object with id, date, and string fields, painless. Now to look at the PersistenceManagerFactory, which google recommends wrapping as a singleton, I hope to use some DI framework in the project (Guice perhaps), but for the moment I'm going to hack it right into the servlets.<br />
<br />
<br />
<b>10:43</b> Alright, singleton copied from google code and modified slightly. Now to add some data.<br />
<br />
I'll create a form on the index page with fields and submit it to an action servlet which will persist it (I won't create a service/business tier just yet) and forward back to the index page.<br />
<br />
I'll also adding the created object to the request before the forward.<br />
<i> </i><br />
<i>Eclipse: oh the irony of your name. hmm, no EL completion in JSP, mff, have to google for request attributes (requestScope, duh).</i><br />
<br />
<br />
<b>11:03</b> and deploy (and enter password)<br />
<br />
<b>11:06</b> Oops, overwrote doGet instead of doPost, fix and publish<br />
<br />
The persistence seems to work, except the EL variable ${requestScope.object.field} is being displayed in plain text and not being interpreted, maybe I've missed something - back to the docs. <br />
<br />
From the mailing list I discovered kindred soles: one needs to add <%@page isELIgnored="false" %> in the JSP, guess it is true by default. Its a pity they don't turn scriplets off by default, I see the docs show extensive use of scriplets within the JSP - there are beginners opening up a world of pain with scriplets in JSP.<br />
<br />
Started using the local server for development.<br />
<br />
<b>11:22</b> yay! working<br />
<br />
Next up, create a custom tag for displaying all records.<br />
<br />
<i>mothership connection coming to take back the pyramids</i> - having a look at some of the mailing list queries.<br />
<br />
<b>11:27</b> SimpleTagHandler here we go. Ah, man: have to write the TLD by hand (well copy and paste and edit by hand). <br />
<br />
<i>do you remember September?</i><br />
<br />
<b>11:39</b> Almost there, need to look at JDO queries and add Tony Allen to the play list.<br />
<br />
<b>11:49</b> Working locally, now to publish..<br />
<br />
<b>11:52</b> And working live, nice. I think a little break, OK?<br />
<br />
<br />
I'm impressed and looking forward to writing applications in java on appengine, I might even port my previous application from python to java. Apparently python and java can run side by side and against the same data. <br />
<br />
Tweaks I'd like to see so far:<br />
<ul><li>Use of EL by default in JSP pages</li>
<li> Saving password when deploying (at least for a session)</li>
<li>Deploy dialog to include fields for app name/version</li>
<li>Email field in the dialog box to be fixed</li>
<li>Maybe some better integration between the wizards and GAEJ (e.g. create servlets)</li>
</ul>Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-8268036115182936052009-03-25T13:36:00.000+02:002009-03-25T13:36:35.609+02:00Streaming Result with JDBC and MySQLThis is another memory extension:<br />
<br />
I'm working on a legacy application with a HUGE amount of meta data (in one table). My poor laptop isn't the best spec'd machine so I'm fairly aware of memory usage of the applications I'm working on and generally don't just throw memory at a problem.<br />
<br />
Anyways, I'm working on part of the application that interigates the data and writes output to a file sequentially: basically read-record, write-to-file, read-record, write-to-file, so when I get the <b>OutOfMemoryError</b> exception I take a closer look and see that the entire result set is read into memory on the statement <i>executeQuery</i> before you can read the <i>ResultSet</i>.<br />
<br />
This creates an itch, there must be a way of specifying read on row from the database, <i>then</i> use the result and then read the next row. After a bit of searching I found this blog: <a href="http://benjchristensen.wordpress.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/">MySQL JDBC Memory Usage on Large ResultSet</a> and it is also buried in the <a href="http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-implementation-notes.html">MySQL connector reference</a>. <br />
<br />
And here is the relevant code:<br />
<br />
<br />
<pre class="programlisting">stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);</pre><br />
Works like a charm.Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-80525205607034547812009-02-05T14:43:00.017+02:002009-02-05T14:48:48.112+02:00Things I will forget [001]This is for manually inserting a record into a postreSQL database that has been generated by hibernate (JPA).<br />
<br />
use '\ds' to sanity check the sequence name ("hibernate_sequence")<br />
<br />
In the insert statement's values section, use 'nextval('hibernate_sequence')' as the ids value, like:<br />
<br />
insert into tablename (id, name) values(nextval('hibernate_sequence'), 'bob')<br />
<br />
<br />
<span style="font-size: x-small;"><span style="color: #cc0000;"><<Blog as memory>></span></span>Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-20706451574403797232008-07-22T11:12:00.008+02:002008-07-22T12:10:00.146+02:00Spring, Annotations and JPA web projectI struggled to set up the latest version of Spring (2.5.4) with JPA using annotations as much as possible for a web project (not using spring MVC). I could find much documentation and the documentation I found was lacking and not specific to the setup I was trying. So here is how I did it for those who need to know.<br />
<br />
<font size="4">Project Setup</font><br />
<br />
I'm using Netbeans, but it shouldn't matter what you are using - I'll keep the IDE out of the description and use external libraries.<br />
<br />
You will need a JPA provider (I'm using hibernate 3.2), Spring libraries and a database (I'm using PostgreSQL). I am also using JUnit4.4, which makes testing with spring a lot easier, I have to edit the testing libraries manually on Netbeans 6.1, as it comes standard with JUnit4.1.<br />
<br />
So, create a web project.<br />
<br />
<font size="4">Setting up JPA</font><br />
<br />
Create a database first, I created one called '<i>deleteme'</i> with user '<i>deleteme</i>' and password '<i>deleteme</i>', so that I will remember to delete it. At some stage.<br />
with your IDE and create a database.<br />
<br />
Next, create a '<i>persistance.xml</i>' file in the '<i>WEB-INF/classes/META-INF</i>' directory, this is what myne looks like:<br />
<font size="1"><br />
</font><br />
<font size="1"><span style="color: rgb(102, 102, 102);"><?xml version="1.0" encoding="UTF-8"?></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"><persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"> <persistence-unit name="<span style="color: rgb(153, 0, 0);">deleteme</span>" transaction-type="RESOURCE_LOCAL"></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"> <provider>org.hibernate.ejb.HibernatePersistence</provider></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"> <properties></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"> <property name="hibernate.hbm2ddl.auto" value="create-drop"/></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"> </properties></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"> </persistence-unit></span><br style="color: rgb(102, 102, 102);" /><span style="color: rgb(102, 102, 102);"></persistence></span></font><br />
<br />
<b>Note</b>: The database details are not in the persitance config file, they will be in the spring config file (more on that later). The only thing you need change is the persistence-unit name which in my case is, 'deleteme'.<br />
<br />
<font size="4">Setting up Spring</font><br />
<br />
Create a new file 'spring.xml' (for example) and add the basic configurations:<br />
<div style="color: rgb(68, 68, 68);"><font size="1"><br />
</font></div><font size="1"><span style="color: rgb(68, 68, 68);"><?xml version="1.0" encoding="UTF-8"?></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"><beans xmlns="http://www.springframework.org/schema/beans"</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> xmlns:context="http://www.springframework.org/schema/context"</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> xmlns:tx="http://www.springframework.org/schema/tx"</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"></span><span style="color: rgb(68, 68, 68);"> <context:annotation-config/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <context:component-scan base-package="<span style="color: rgb(153, 0, 0);">com.gamatam.example</span>" /></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <property name="driverClassName" value="org.postgresql.Driver"/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <property name="url" value="jdbc:postgresql://localhost/<span style="color: rgb(153, 0, 0);">deleteme</span>"/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <property name="username" value="<span style="color: rgb(153, 0, 0);">deleteme</span>"/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <property name="password" value="<span style="color: rgb(153, 0, 0);">deleteme</span>"/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </bean></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <property name="dataSource" ref="dataSource"/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </bean></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <property name="entityManagerFactory" ref="entityManagerFactory" /></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </bean></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> <tx:annotation-driven /></span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"></beans></span></font><br />
<br />
<b>Note</b>: I setup the datasource in the spring configuration, as the configuration is more or less in one place and it makes unit testing easier (rather than using a datasource from the J2EE container).<br />
<br />
The different namespaces needed tripped me up the first time I set this up, its a great idea, but does create more confusion to new users.<br />
<br />
Basically, I setup a datasource for the database and an EntityManagerFactoryBean, which will find the persistance configuration. Then add the exception translation and transaction management and specify that the config is annotation driven. Thats it!<br />
<br />
<font size="4">First Test</font><br />
<br />
Now you can create your first test to see that the configuration files are being loaded OK etc.. Here is myne:<br />
<div style="color: rgb(68, 68, 68);"><font size="1"><br />
</font></div><font size="1"><span style="color: rgb(68, 68, 68);">package com.gamatam.example;</span><br style="color: rgb(68, 68, 68);" /><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import org.junit.AfterClass;</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import org.junit.BeforeClass;</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import org.junit.Test;</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import org.junit.runner.RunWith;</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import org.springframework.test.context.ContextConfiguration;</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">import static org.junit.Assert.*;</span><br style="color: rgb(68, 68, 68);" /><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">/**</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> *</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> * @author brians</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> */</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">@RunWith(SpringJUnit4ClassRunner.class)</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">@ContextConfiguration(locations = { "file:web/WEB-INF/<span style="color: rgb(153, 0, 0);">spring.xml</span>" })</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">public class Basics {</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> @Test</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> public void first(){</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> }</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> </span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> public Basics() {</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> }</span><br style="color: rgb(68, 68, 68);" /><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> @BeforeClass</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> public static void setUpClass() throws Exception {</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> }</span><br style="color: rgb(68, 68, 68);" /><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> @AfterClass</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> public static void tearDownClass() throws Exception {</span><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);"> }</span><br style="color: rgb(68, 68, 68);" /><br style="color: rgb(68, 68, 68);" /><span style="color: rgb(68, 68, 68);">}</span></font><br />
<br />
<b>Note</b>: With the '<i>RunWith</i>' and '<i>ContextConfiguration</i>' annotations, testing spring becomes a breeze, no more excuses :(<br />
<br />
If that is working for you, you are past the worst part of your project and can go on to code.<br />
<br />
<font size="4">Whats Next?</font><br />
<br />
Well, next create an entity bean and test it, create a DAO for it and test it, create your business/service layer with transactinos and test it. That will be in part two..<br />
<br />
<i>This is what worked for me, you may not like it but comments on it anyway, I'd love to here from you.</i><br />
<br />
Brian<br />
<br />
<font size="1"></font><br />
<font size="1"></font><br />
<font size="1"></font><br />
<font size="1"><span style="color: rgb(68, 68, 68);"></span></font>Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-11681793762346818492008-06-18T13:24:00.000+02:002008-06-23T13:42:07.756+02:00Plain ol' Servlets and JSP<blockquote></blockquote>I reached a realization after many years of working with web frameworks and creating a few back when there weren't any to be had: web frameworks don't always save you time and has everybody forgotten how to code with servlets JSPs and tag libraries?<br /><br />What pushed me over the edge was trying to code in an agile way using JSF. JSF is a nice idea, at least it doesn't tie you to the framework too much (extending action classes etc), but it is so loosely coupled that a typo (and I make loads) can cause a half day loss of work tracking down the error and I haven't been through that kind of debugging since C/C++, um, and mobile device programming.<br /><br />I also got tired of writing configuration data in multiple xml and property files: set up the framework in the web.xml file, then off to the frameworks action config file, then the mapping file etc.. yuck.<br /><br />About 6 years ago I wrote a framework using XML and XSLT when it looked like XSLT was the best thing for view abstraction (hahaha). I had a nicely abstracted design, with a factory for choosing the action class, another for choosing the XSLT file and another for the SQL. This was all rather neat and worked well, though took a lot explaining to my colleagues, but as they weren't familiar with OOP architecture (architecture in general) I arrogantly thought once they saw the whole picture all would be forgiven...<br /><br />A few years later there was call to use the same application and I took a look through the system again and realized that all the configuration could be done within the web.xml file: as all the logic was based around the request (it was a report based application), I could write a base servlet that handled the transforms and the configuration could be written into the servlet parameters and the mappings. It simplified the whole framework into a very manageable piece of code, I wouldn't say the same about the XSLT though..<br /><br />The point of the diatribe is that we tend to go off and create a 'gatekeeper' servlet for handling all the requests and then a factory for mapping requests to actions, forgetting that a servlet is an action in itself. The other problem is the actions normally created are normally created, I suppose, to protect ourselves from all that HTTP request and response stuff, and then we end up passing it all through to the action ANYWAY, as its, um, pretty essential.<br /><br />Since working on distributed applications servicing different types of clients I have used a clear business (or service) layer which means that the servlet becomes a translation layer only (getting parameters from the request etc..). Together with apache's beanutils there is really not much to do.<br /><br />On the view side I again realized a flaw while using JSF: AJAX hit the scene but JSF or struts for that matter, had no support for it. So if you use these frameworks you are tied to whatever components they come up with including the javascript libraries and look and feel etc.<br /><br />The other point is that HTML is already one language to learn, why bother with learning another (none-standard) way of doing it? Looking at the RFCs, HTML itself is going to become more complicated, why reinvent the wheel? I'd prefer to write my forms by hand and insert the values where needed, which brings me to my last point:<br /><br />Why are more people not using tag libraries? They are easy to use and they do exactly what you need them to do. Together with EL and JSTL you can create some very clean and understandable views. There are some drawbacks and work arounds, but if more people were using them they would improve. Tool support is also a bit iffy: Netbeans has great support, but could be improved.<br /><br />I've just brushed on the basics here and am not bashing frameworks completely, they have there place, but they don't have to be used everywhere in every situation.<br /><br />I'd like to start not a framework, but rather a meme for using basic servlet/JSP for web development. If I get much interest from this blog, my next blog will be on the basics of using this meme.Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-82665882462286467172008-01-28T09:35:00.001+02:002008-07-30T15:02:21.843+02:00installing tomcat and apache on linuxThis is mainly for my own record, I keep on having to do it from scratch and making it up on my way. The box I'm installing on is running redhat (or whatever it is called these days), not my choice - I prefer the debian / ubuntu setups, but I'm not fussed as they all work similarly.<br /> <br /><span style="color: rgb(204, 0, 0);"> Warning: This needs to be edited and formatted to make better sense and I may not get round to it..</span><br /> <br /><span style="font-weight: bold;"> Step One: Install Java</span><br /> As java is so dead simple to install and manage on linux, I download and install it manually with little configuration<br /> <br /><ol><li>Get the installer onto the box - I used lynx on the server to navigate from http://java.sun.com to the download area and download the installer, its not that clear using a text browser, but is possible (remember to press 'enter' on the agreement checkbox).</li><li>Run the install (chmod +x to make it executable) in the directory you want it installed, which in my case was '/usr/local'.</li><li>Create a symlink 'ln -s ..' to the jdk directory (/usr/local/java). My previous install I used the ./defaultjava ./currentjava etc, but I never needed it, so away it goes.<br /></li></ol> <br /> That is for java, I never create JAVA_HOME global environment variables as they can get overwritten when installing something else, it also makes it easier to swap java version and I've never had the need for it.<br /> <br /><span style="font-weight: bold;"> Step 2: Install tomcat</span><br /> A bit more complicated, asd but mainly because I split out the tomcat directories (configuration, logging, web sites and working directories all go in linux freindly places (mostly).<br /><ol><li>Download with wget: 'wget http://apache.is.co.za/tomcat/tomcat-6/v6.0.14/bin/apache-tomcat-6.0.14.tar.gz'. Check which version of tomcat you want first and replace the URL.</li><li>Extract tomcat: I extract the application to '/java', because thats what makes sense to me. Some people would extract it to /usr/lib or ./bin or ./service or something.</li><li>Configuration: move tomcat's conf directory to /etc/tomcat</li><li>Compile the daemon: extract './bin/jsvc.tar.gz' and follow the instructions at http://tomcat.apache.org/tomcat-6.0-doc/setup.html</li><li>edit ./native/Tomcat5.sh e.g:<br /></li></ol> <br /># Adapt the following lines to your configuration<br />JAVA_HOME=/usr/local/java1.6<br />CATALINA_HOME=/java/tomcat<br />DAEMON_HOME=${CATALINA_HOME}/bin/jsvc-src<br />TOMCAT_USER=brians<br /><br /># for multi instances adapt those lines.<br />TMP_DIR=/var/tmp<br />PID_FILE=/var/run/jsvc.pid<br />CATALINA_BASE=/etc/tomcat<br /><br />#CATALINA_OPTS="-Djava.library.path=/home/jfclere/jakarta-tomcat-connectors/jni/native/.libs"<br />CLASSPATH=\<br />$JAVA_HOME/lib/tools.jar:\<br />$CATALINA_HOME/bin/commons-daemon.jar:\<br />$CATALINA_HOME/bin/bootstrap.jar<br /> and change this line:<br /> $DAEMON_HOME/src/native/unix/jsvc \<br /> to:<br /> $DAEMON_HOME/jsvc \<br /> <br /> <br /> and -outfile /var/log/tomcat/stdout \<br /> -errfile /var/log/tomcat/stderr \<br /> -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \<br /> -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \<br /><br />then chown tomcat.tomcat to /var/log/tomcat<br /> <br /> test with (remember to create the user tomcat will run under first):<br /> sudo sh ./native/Tomcat5.sh start<br /> add to /etc/init.d<br /> <br /> * change permissions on/etc/tomcat to tomcat and created directory /var/log/tomcat<br /> <br /> <br /><span style="font-weight: bold;"> Further Tomcat configuration:</span><br /> Now to setup where the work folder is and setup the webapps.<br /> <br /> mkdirs:<br /> <br /> /var/www/html/webapps/hostname - these are for the manager installed apps and hot deploy WARs<br /> <br /> /var/tomcat/work/hostname - these are for the tomcat generated files (jsp/servlet compiled)<br /> <br /> /var/log/tomcat/ - for the log files<br /> <br /> Then configure the server.xml:<br /> host name="gamatam.com" appbase="/var/www/html/webapps/gamatam" workdir="/var/tomcat/work/gamatam" upackwars="true" autodelpoy="true" xmlvalidation="false" xmlnamespaceaware="false"<br /> alias www.gamatam.com /alias<br /> /host<br /> <br /> It might be a good idea to make a backup of the server.xml file and then delete all the comments, makes it clearer.<br /> <br /><span style="font-weight: bold;"> Tomcat - Apache configuration:</span><br /> Not as bad as you would think..<br /> <br /> You need mod_jk installed (its a module for apache), you may be able to yum or apt-get it, I can't so i'm going to download it (rather than compile it). This might not work out..<br /> <br /> Following the trail from http://tomcat.apache.org/connectors-doc/, download the right version for your linux and apache version (important)<br /> <br /> And when all else fails, copy it from another location, more on this once the server's yum sources are set properly.<br /> <br /> Add the following in the server.xml Engine:<br /> <br /> listener classname="org.apache.jk.config.ApacheConfig" modjk="/etc/httpd/modules/mod_jk.so" confighome="/etc/tomcat" workersconfig="/etc/tomcat/conf/jk/workers.properties" jkworker="default" jklog="/var/log/tomcat/mod_jk.log" noroot="false"<br /> <br /> you will need to create<br /> /etc/tomcat/conf/jk/workers.properties and start with the default:<br /> <br /> worker.list=default<br /> <br /> worker.default.type=ajp13<br /> worker.default.host=localhost<br /> worker.default.port=8009<br /> <br /> and then add the following to the apache config, which in centos/craphat is at /etc/httpd/conf/httpd.conf:<br /> <br /> #TOMCAT#<br /> Include /etc/tomcat/conf/auto/mod_jk.conf<br /> <br /> That includes the tomcat related configuration and any virtual hosts etc and does the mapping.Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0tag:blogger.com,1999:blog-5123568531445774834.post-59624509923328603242007-04-12T10:30:00.000+02:002007-04-12T11:19:50.043+02:00Trukese NavigatorI discovered an interesting quote while working through <span style="font-style: italic;">'Drawing on the Right Side of the Brain'</span> by Betty Edwards. There is a side bar reference to a reference by Thomas Gladwyn on the <a href="http://en.wikipedia.org/wiki/Chuukese_language">Trukese</a> navigators ability to sail to another island by '..imaging the position of his destination relative to the position of other islands. As he sails along, he constantly adjusts his direction according to his awareness of his position thus far.'<br /><br />In contrast, the European navigator '..begins with a plan that can be written in terms of directions, degrees of longitude and latitude, estimated time of arrival at separate points in the journey.' which is then put into place and followed to a tee.<br /><br />The point of the reference in the book was to highlight the difference between left and right hemisphere mode of thinking, but it works as a great analogy for the agile versus waterfall approach to development too. In fact, if you google 'trukese navigator' you will find it being used in reference to teaching, communication and management.<br /><br />It reminds of Kent Beck's analogy of learning to drive a car by aiming the steering wheel before starting the car, as apposed to making corrections as you go along. What I like about the Trukese quote is that the other method stilled worked, and for certain people the 'big plan' works for them to, but the cost is very different and sometimes you discover America instead of India.Brian Silberbauerhttp://www.blogger.com/profile/03384568981719423913noreply@blogger.com0