<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>SeeSaw's blog: Tag java</title>
    <link>http://blog.seesaw.it/articles/tag/java</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>...read our minds.</description>
    <item>
      <title>How to sell fluff to James Gosling...</title>
      <description>&lt;p&gt;The &lt;a href="http://www.javajournal.it"&gt;JavaJournal blog&lt;/a&gt; has just published an &lt;a href="http://www.javajournal.it/blog/2006/09/18/1158533280000.html"&gt;article&lt;/a&gt; on how I sold a funny T-Shirt to James Gosling at the &lt;a href="http://it.sun.com/eventi/jc06/"&gt;last Italian JavaConference&lt;/a&gt;. We had a lot of fun there with the &lt;a href="http://www.jugpadova.it"&gt;&lt;span class="caps"&gt;JUG&lt;/span&gt; Padova&lt;/a&gt; guys&amp;#8230; nice to see someone remember the great gig I did :D&lt;/p&gt;


	&lt;p&gt;JavaJournal is a brand new magazine about Java and Software development. It&amp;#8217;s very hard to set up magazines like this in Italy but it seems those guys are motivated and the whole story looks really promising!&lt;/p&gt;


	&lt;p&gt;I wish you the best JavaJournalers!!! ...and who knows, I could find myself writing for them sooner or later&amp;#8230;&lt;/p&gt;
</description>
      <pubDate>Mon, 18 Sep 2006 00:54:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:b8f89cf3-86b5-491e-aa6c-bdbb86a49564</guid>
      <author>Paolo</author>
      <link>http://blog.seesaw.it/articles/2006/09/18/how-to-sell-fluff-to-james-gosling</link>
      <category>The outer world</category>
      <category>Java</category>
      <category>java</category>
      <category>javajournal</category>
      <category>jugpadova</category>
      <category>james</category>
      <category>gosling</category>
      <category>tshirt</category>
      <trackback:ping>http://blog.seesaw.it/articles/trackback/6729</trackback:ping>
    </item>
    <item>
      <title>Getting MIME type from a file</title>
      <description>&lt;p&gt;It&amp;#8217;s pretty simple: just grab activation framework from the web and type:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ "&gt;import javax.activation.MimetypesFileTypeMap;
import java.io.File;
...
File file = new File(&amp;quot;WhoAmI.jpg&amp;quot;);

System.out.println(&amp;quot;MIME type of &amp;quot; +
  file.getName() + &amp;quot; is &amp;quot; +
  new MimetypesFileTypeMap().getContentType(file)
);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The expected output is:&lt;/p&gt;


	&lt;p&gt;&lt;span class="shell"&gt;&lt;span class="caps"&gt;MIME&lt;/span&gt; type of WhoAmI.jpg is image/jpeg&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;simple and effective, isn&amp;#8217;t it?&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;: If you want to detect types other than simple images you should integrate the activation framework default list as stated in the &lt;a href="http://java.sun.com/products/javabeans/glasgow/javadocs/javax/activation/MimetypesFileTypeMap.html"&gt;javadoc&lt;/a&gt; .
For example detection of a zip archive can be done by adding this:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ "&gt;MimetypesFileTypeMap mt = new MimetypesFileTypeMap();
mt.addMimeTypes(&amp;quot;application/x-zip zip ZIP&amp;quot;);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
      <pubDate>Sat, 09 Sep 2006 22:56:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ff9cc76a-73ee-4702-b244-b85c13fa546b</guid>
      <author>Michele</author>
      <link>http://blog.seesaw.it/articles/2006/09/09/getting-mime-type-from-a-file</link>
      <category>Java</category>
      <category>Tips &amp; Tricks</category>
      <category>mime</category>
      <category>type</category>
      <category>file</category>
      <category>java</category>
      <trackback:ping>http://blog.seesaw.it/articles/trackback/5802</trackback:ping>
    </item>
    <item>
      <title>seesaw Series: Java, Ruby and Enterprise</title>
      <description>&lt;p&gt;During the last few months I read a lot about Java, Ruby on Rails and enterprise applications.
I realized with surprise that these topics were always covered from the technological point of view: scalability, performance, integration and other issues were well addressed and discussed. But something in my mind kept telling me they were somehow heading to the wrong direction. I spent some time thinking and gathering past experiences and came up with a strong belief.&lt;/p&gt;
&lt;p&gt;Trust me, technical issues are not the real point about the Java vs RoR debate. Enterprise applications, as the name suggests, are developed in enterprises, not totally-awesome-oh-so-web2.0-startups or long haired communities. Now ask yourself: who’s holding the development keys inside an enterprise? The IT manager. He’s a strange guy, hard to interact with. Doesn’t understand “scalability”, “integration” or “performance”. Doesn’t eat code for lunch. He prefers the sound of terms like “costs”, “investments”, “ROI” and guess what? Money. That’s why I won’t write about the Java vs RoR debat from the IT manager point of view.&lt;/p&gt;


	&lt;p&gt;Here in SeeSaw we use either Java and Ruby on Rails. We actually do love RoR. We started some project with it and found it invaluable. We’re spending a growing amount of time with rails. But we also love Java. We couldn’t hate it: it helps us pay the bills. In fact the experience tells us that if you want to do consulting with big companies, you’ve got to have Java in your pocket.&lt;/p&gt;


	&lt;p&gt;Let’s digg this point. An enterprise project differs from the other kinds of projects in team dimension and software lifetime. We’ll call it the five-by-five rule as it usually involves more than five developers and will stay on line at least for five years. In this context the IT manager target is to maintain the highest quality with the lowest costs for the whole software lifetime. How? For the answer &lt;a href="http://blog.seesaw.it/xml/rss20/feed.xml"&gt;add our feed&lt;/a&gt; to your news reader ;-)&lt;/p&gt;</description>
      <pubDate>Sat, 24 Jun 2006 15:48:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ae24e1b6-ec56-48f6-a127-93bec4eef975</guid>
      <author>Jacopo Murador</author>
      <link>http://blog.seesaw.it/articles/2006/06/24/seesaw-series-java-ruby-and-enterprise</link>
      <category>Java</category>
      <category>Ruby + Rails</category>
      <category>ruby</category>
      <category>Ruby On Rails</category>
      <category>java</category>
      <category>enterprise</category>
      <trackback:ping>http://blog.seesaw.it/articles/trackback/99</trackback:ping>
    </item>
    <item>
      <title>Ruby@JUGPadova has been a big success!</title>
      <description>&lt;p&gt;&lt;img src="http://static.flickr.com/53/152552045_cd5e301e85_m.jpg" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Hey guys, Paolo and Jacopo held a speech at the last &lt;a href="http://www.jugpadova.it"&gt;&lt;span class="caps"&gt;JUG&lt;/span&gt; Padova&lt;/a&gt; meeting. I can proudly say it has been a big big success!&lt;/p&gt;


	&lt;p&gt;You can find our photostream &lt;a href="http://www.flickr.com/photos/seesawstaff/sets/72157594144070808/"&gt;here&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;We actually love to digg things in public and really seems  attendants appreciated our effort. It&amp;#8217;s not the first time we&amp;#8217;re going public but this event has been somehow special. It gathered more people, more interest, more ideas.&lt;/p&gt;


	&lt;p&gt;I want to personally thank &lt;a href="http://liquiddevelopment.blogspot.com/"&gt;ChiaroScuro&lt;/a&gt; who had enough patience to not kill me during our crazy and tiring weekend.&lt;/p&gt;


	&lt;p&gt;Well, I guess we&amp;#8217;ll repeat this meeting somewere else someday&amp;#8230; so stay tuned!&lt;/p&gt;
</description>
      <pubDate>Wed, 24 May 2006 19:34:08 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5dfabbaa-d9b3-43cb-b6d9-cae3875612ef</guid>
      <author>Paolo</author>
      <link>http://blog.seesaw.it/articles/2006/05/24/ruby-jugpadova-has-been-a-big-success</link>
      <category>Java</category>
      <category>Ruby + Rails</category>
      <category>Trends and Technology</category>
      <category>ruby</category>
      <category>Ruby On Rails</category>
      <category>java</category>
      <category>enterprise</category>
      <category>meeting</category>
      <category>jug</category>
      <trackback:ping>http://blog.seesaw.it/articles/trackback/76</trackback:ping>
    </item>
    <item>
      <title>Cannot change charset from 'UTF8' to 'UTF-8'</title>
      <description>&lt;p&gt;A few months ago I run into a problem using &lt;a href="http://jakarta.apache.org/tapestry"&gt;Tapestry&lt;/a&gt; over &lt;span class="caps"&gt;BEA&lt;/span&gt;  Weblogic 8.1 &lt;span class="caps"&gt;SP2&lt;/span&gt;. 
During the execution of a beginPageRender I issued  a redirection and got a weird:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;     org.apache.hivemind.ApplicationRuntimeException: 
     Attempt to change ContentType after calling getWriter() 
     (cannot change charset from 'UTF8' to 'UTF-8')&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Many people from the Tapestry mailing list continue to ask me a solution to this problem so I&amp;#8217;m posting it here for future reference.&lt;/p&gt;
&lt;h4&gt;How to trigger the Exception&lt;/h4&gt;


	&lt;p&gt;I couldn&amp;#8217;t immediately figure out what was going on but I was pretty sure it was a Weblogic fault, as my app run well under Tomcat.&lt;/p&gt;


	&lt;p&gt;To simulate the error you can just set up a page like this one:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;    public abstract class Test extends     
           org.apache.tapestry.html.BasePage {
      // do nothing, just redirect to Home when invoked
      public Test(){
        addPageBeginRenderListener(new PageBeginRenderListener(){
          public void pageBeginRender(PageEvent event) {
            throw new RedirectException(&amp;quot;Home&amp;quot;);
          }
        });
      }
    }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I&amp;#8217;ve got two html templates: &amp;#8220;Home.html&amp;#8221; and &amp;#8220;Test.html&amp;#8221;. both of them do not have components, just plain html.
I wanna perform a redirection from Test to Home, so I try to call http://localhost:7001/app?page=Test&amp;#38;service=page.
On tomcat this call performs the redirection to the &amp;#8220;Home&amp;#8221; page without generating errors.&lt;/p&gt;


	&lt;p&gt;On &lt;span class="caps"&gt;WLS 81 I&lt;/span&gt; got the infamous IllegalStateException &amp;#8220;Attempt to change ContentType after calling getWriter() (cannot change charset from &amp;#8216;UTF8&amp;#8217; to &amp;#8216;UTF-8&amp;#8217;)&amp;#8221;&lt;/p&gt;


	&lt;h4&gt;Why does it happen?&lt;/h4&gt;


	&lt;p&gt;It seems that the servletResponse is already committed during redirection. 
The ServletWebResponse.getPrintWriter(ContentType) method tries to reset the contentType and get a new writer without checking if it needs to or not&amp;#8230;
Servlet specifications are not clear on this, or at least, server implementations not always behave the same.&lt;/p&gt;


	&lt;h4&gt;Solution 1: Hack Tapestry&lt;/h4&gt;


	&lt;p&gt;This first solution involves a modification of a Tapestry class, so you need to download the source and then rebuild the distribution. This is a way, but I really don&amp;#8217;t encourage its adoption as Tapestry is evolving quickly and  you could get stuck on your very own hacked version.&lt;/p&gt;


	&lt;p&gt;This is the solution I submitted to the &lt;a href="http://issues.apache.org/jira/browse/TAPESTRY-730"&gt;Tapestry jira&lt;/a&gt; too. Modify the &lt;strong&gt;ServletWebResponse.getPrintWriter(...)&lt;/strong&gt; method this way.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;     public PrintWriter getPrintWriter(ContentType contentType) throws IOException  {
         Defense.notNull(contentType, &amp;quot;contentType&amp;quot;);
         if (_needsReset)
             reset();
         _needsRes et = true;
         if (!_servletResponse.isCommited( ))
              _servletResponse.setContentType(contentType.toString());
          }
         try {
             return _servletResponse.getWriter();
         } catch (IOException ex) {
             throw new ...
         }
     }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This will check if the contentType has already been set or not, and will avoid the Exception to be thrown.&lt;/p&gt;


	&lt;h4&gt;Solution 2: Cheat on it!&lt;/h4&gt;


	&lt;p&gt;A smarter solution is to be less invasive on the Tapestry framework. I&amp;#8217;ve chosen to wrap my ServletResponse objects in smarter ones, that can deal with the encoding problem.&lt;/p&gt;


	&lt;p&gt;So I wrote this:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;     public class NotUpsettingHttpServletResponse extends  
                  HttpServletResponseWrapper {
       private boolean gotWriter;
       private boolean gotOutputStream;
       public NotUpsettingHttpServletResponse(HttpServletResponse httpServletResponse) {
         super(httpServletResponse);
       }
       public void setContentType(String contentType) {
         if (isCommitted() || gotWriter || gotOutputStream){
           // skipping response.setContentType(..);&amp;quot;);
         } else {
           super.setContentType(contentType);
         }
       }
       public PrintWriter getWriter() throws IOException {
         gotWriter = true;
         return super.getWriter();
       }
       public ServletOutputStream getOutputStream() throws IOException {
         gotOutputStream = true;
         return super.getOutputStream();
       }
     }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And applied it on every call with a ServletFilter like this one:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;     public class ContentTypePatchFilter implements Filter  {
       public void init(FilterConfig filterConfig) throws ServletException {
         log.debug(&amp;quot;ContenTypePatchFilter started.&amp;quot;);
       }
       public void doFilter(ServletRequest servletRequest,
                            ServletResponse servletResponse, 
                            FilterChain filterChain) 
                            throws IOException, ServletException {
         HttpServletResponse res  = (HttpServletResponse) servletResponse;
         NotUpsettingHttpServletResponse myResponse = new NotUpsettingHttpServletResponse(res);
         filterChain.doFilter(servletRequest,myResponse);
       }
    }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Of course the last step is to set up the filter in your web.xml:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;      &amp;lt;filter&amp;gt;
        &amp;lt;filter-name&amp;gt;
          contentTypePatchFilter
        &amp;lt;/filter-name&amp;gt;
        &amp;lt;filter-class&amp;gt;
          it.seesaw.ContentTypePatchFilter
        &amp;lt;/filter-class&amp;gt;
      &amp;lt;/filter&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This approach solves the problem. Every response is now smart enough to let your app go without considering unecessary setContentType calls.&lt;/p&gt;


	&lt;p&gt;Hope this can help all those people who keep contacting me. Let me know if it has worked for you too&amp;#8230;&lt;/p&gt;</description>
      <pubDate>Fri, 14 Apr 2006 15:24:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:75e23c29-7a13-4e63-9fec-5f2995c6af4a</guid>
      <author>Paolo</author>
      <link>http://blog.seesaw.it/articles/2006/04/14/cannot-change-charset-from-utf8-to-utf-8</link>
      <category>Web</category>
      <category>tapestry</category>
      <category>bea</category>
      <category>encoding</category>
      <category>utf-8</category>
      <category>exception</category>
      <category>servlet</category>
      <category>filter</category>
      <category>java</category>
      <category>web</category>
    </item>
  </channel>
</rss>
