Montag, 14. Dezember 2009

Disable IPv6 in Debian Lenny Linux

And here is how to do this:
  • At first the stuff every web site is telling us: In /etc/modprobe.d/aliases replace/add the following mappings: alias net-pf-10 off alias ipv6 off (I found this at fak3r.com)
  • If you are using a firewall script which loads all available module before setting up the firewall, add the following lines to /etc/modprobe.d/aliases: alias ip6_queue.ko off alias ip6table_filter.ko off alias ip6table_mangle.ko off alias ip6table_raw.ko off alias ip6table_security.ko off alias ip6_tables.ko off alias ip6t_ah.ko off alias ip6t_eui64.ko off alias ip6t_frag.ko off alias ip6t_hbh.ko off alias ip6t_hl.ko off alias ip6t_HL.ko off alias ip6t_ipv6header.ko off alias ip6t_LOG.ko off alias ip6t_mh.ko off alias ip6t_REJECT.ko off alias ip6t_rt.ko off alias nf_conntrack_ipv6.ko off You can do this by executing: for module in `ls /lib/modules/YOUR-KERNEL-VERSION/kernel/net/ipv6/netfilter/`; do echo "alias $module off" >> /etc/modprobe.d/aliases; done
Hope this helps :-)

Donnerstag, 3. Dezember 2009

Apache2 httpd, Apache Tomcat6 and rewrite problems

While configuring a Apache2 as Proxy for a bunch of Tomcats behind I found many postings that says "Use mod_rewrite and this set of rules" or "you have to use ajp and mod_jk". After some rtfm I found out that setting up a Apache2 httpd with multiple Apache Tomcats behind mapped using mod_proxy is pretty simple and straight forward. here is the HowTo:
1. Add a site to the apache2:
cat /etc/apache2/sites-enabled/artifactory
<Location /artifactory/>
    ProxyPass http://127.0.0.1:8100/artifactory/
    Order deny,allow
    Allow from all
</Location>
2. Enable mod_proxy by creating the following links (ln -s target) in /etc/apache2/mods-enabled/
proxy.conf -> ../mods-available/proxy.conf
proxy_http.load -> ../mods-available/proxy_http.load
proxy.load -> ../mods-available/proxy.load
3. Modify the content of /etc/apache2/mods-enabled/proxy.conf :
<IfModule mod_proxy.c>
ProxyRequests Off

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

</IfModule>
4. reload the apache2 server:
/etc/init.d/apache2 reload
5. modify $TOMCAT_HOME/conf/server.xml
Change from:
<Connector port="8100" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443" />
to
<Connector port="8100" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443"
proxyName="YourDomain.YourTLD" proxyPort="80"/>

Montag, 14. September 2009

DragImagePainter or Getting Around isDragImageSupported() on Windows

Last week I had an interesting conversation with a project manager at a meeting of the Scrum User Group in Dresden. He asked me why so many common tasks need to be reprogrammed in every project. I tried to answer that question and argued that things need to be implemented in a different way for different purposes... But today I came to the conclusion the he's right. Reimplementing common tasks is expensive and it happens too often. "The customer wants to relayout some components on the fly using Drag and Drop. While dragging a small drag image of the dragged component should be visible near the mouse pointer." - Sounds like a common use case to me. But Drag and Drop (DnD) in Swing does not support this. Of course Swing supports Drag and Drop out of the box - but only for a small amount of components. I don't know why this feature is missing in a framework which is in use since a decade. On my way implementing this feature I stumble upon the method isDragImageSupported() of the class java.awt.dnd.DragSource. Windows does not support adding a DragImage to the mouse pointer. Google told me to look at Geertjan's Blog. He wrote a nice and informative article how to implement this feature. Nicely done! But doing it the way he did means doing it again and again and the poor customer needs to pay for this :) As I want customers of IT companies to be happy I tried to save the world. First of all I called my brother in arms rosh. With combined holy hand grenades we wrote a kewl class called DragImagePainter. It needs to be instantiated in the java.awt.dnd.DragSourceListener. In method dragOver of the java.awt.dnd.DragSourceListener a call to the function paintDragImage will do the magic. Feel free to use AND REUSE the following piece of code:
/**
* Utility class for painting a scaled and opaque image representation of a
* dragged component while it's being dragged.
*
* @author Richi
*
*/
public class DragImagePainter {
private final AlphaComposite ALPHA_COMPOSITE = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
private final JComponent rootComponent;
private final JComponent draggableComponent;
private final int offsetY;
private final int imageWidth;

private Point lastKnownCursorPosition;

/**
 * @param rootComponent
 *            the root component of the current window
 * @param draggableComponent
 *            the component which is going to be dragged
 */
public DragImagePainter(JComponent rootComponent, JComponent draggableComponent) {
 this.rootComponent = rootComponent;
 this.draggableComponent = draggableComponent;
 this.offsetY = -15;
 this.imageWidth = 50;
}

/**
 * Paints a scaled and opaque image representation of the draggableComponent
 * provided in the constructor near the current mouse pointer position.
 *
 * @param currentCursorPositionX
 * @param currentCursorPositionY
 */
public void handleDragOver(int currentCursorPositionX, int currentCursorPositionY) {
 boolean imagePositionChanged = imagePositionChanged(currentCursorPositionX, currentCursorPositionY);
 if (imagePositionChanged) {
  double scaleFactor = calculateScaleFactor();
  int imageHeight = calculateImageHeight(scaleFactor);
  if (!isFirstRun())
   repaintLastKnownImageArea(imageHeight);
  Graphics2D rootComponentGraphics = (Graphics2D) rootComponent.getGraphics();
  paintDragImage(currentCursorPositionX, currentCursorPositionY, scaleFactor, rootComponentGraphics);
  lastKnownCursorPosition = new Point(currentCursorPositionX, currentCursorPositionY);
 }
}

/**
 * Needs to be called on {@link DragSourceListener}.dragEnd() to repaint the
 * area of the last painted drag image
 */
public void handleDropEnd() {
 double scaleFactor = calculateScaleFactor();
 int imageHeight = calculateImageHeight(scaleFactor);
 repaintLastKnownImageArea(imageHeight);
}

double calculateScaleFactor() {
 return (double) imageWidth / draggableComponent.getWidth();
}

private int calculateImageHeight(double scaleFactor) {
 return (int) Math.ceil(draggableComponent.getHeight() * scaleFactor);
}

boolean imagePositionChanged(int currentCursorPositionX, int currentCursorPositionY) {
 return isFirstRun() || lastKnownCursorPosition.x != currentCursorPositionX
   || lastKnownCursorPosition.y != currentCursorPositionY;
}

void repaintLastKnownImageArea(int height) {
 rootComponent.paintImmediately(lastKnownCursorPosition.x, lastKnownCursorPosition.y + offsetY, imageWidth,
   height);
}

boolean isFirstRun() {
 return lastKnownCursorPosition == null;
}

void paintDragImage(int currentCursorPositionX, int currentCursorPositionY, double scaleFactor,
  Graphics2D rootComponentGraphics) {
 Graphics2D dragPictureGraphics = (Graphics2D) rootComponentGraphics.create();

 dragPictureGraphics.translate(currentCursorPositionX, currentCursorPositionY + offsetY);
 dragPictureGraphics.scale(scaleFactor, scaleFactor);
 dragPictureGraphics.setComposite(ALPHA_COMPOSITE);

 draggableComponent.paint(dragPictureGraphics);
}

}
Use in this way:
@Override
public void dragDropEnd(DragSourceDropEvent dragSourceDropEvent) {
dragImagePainter.handleDropEnd();
}
@Override
public void dragOver(DragSourceDragEvent dragSourceDragEvent) {
dragImagePainter.handleDragOver(dragSourceDragEvent.getX(), dragSourceDragEvent.getY());
}

Freitag, 11. September 2009

Who is doing QA on selfhtml.org?

Not many words on this:
if (document.Testform.Art[0].checked == true) { ... }

Donnerstag, 3. September 2009

Sony Ericsson W995, Google Calendar and Google Sync

After a long time a shorty:
I'm using gmail and the google calendar. I was searching for a cell phone which is able to sync with my google accounts. I've chosen the W995 since its price is the half of a G-Phone/I-Phone or Palm Pre and it fits my needs. Its fast, has a good battery AND since today it's able to synchronize my google calendar items and mails. All you have to do is to go to menu>organizer>synchronisation and set up a new Exchange Active Sync account:
  • Server address : https://m.google.com
  • Domain : Empty - this means leave this field blank
  • Username : your.name@googlemail.com (your full email address)
  • Password : 31337

Samstag, 20. Juni 2009

Stripes Image Streamingresolution

I'm often asked how to stream an image from sources like a database blob or a folder which is not shared by the servlet container to the client using stripes. This is done by extending the class net.sourceforge.stripes.action.StreamingResolution. The most simple way:
public Resolution view( ) {
  ...
  String mimeType = getContext().getServletContext().getMimeType(fileName);
  final byte[] file = readFileToByteArray(absolutFilePath);//this method needs to be implemented
  return new StreamingResolution(mimeType) {
     @Override
     protected void stream(HttpServletResponse response) throws Exception {
        response.getOutputStream().write(file);
     }
  };
}
When streaming static content I'd recommend a more complex solution using headers to modify file names or caching behavior of the browser:
public Resolution view( ) {
  ...
  String mimeType = getContext().getServletContext().getMimeType(fileName);
  final byte[] file = readFileToByteArray(absolutFilePath);//this method needs to be implemented
  return new StreamingResolution(mimeType) {
     @Override
     protected void stream(HttpServletResponse response) throws Exception {
        setFilename("TheHolyHandGranade.gif");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, 30);
        Date expires = calendar.getTime();
        response.setDateHeader("Expires", expires.getTime());
        response.getOutputStream().write(file);
     }
  };
}
Hope this helps :-)

Donnerstag, 18. Juni 2009

Partially mocking the class under test

When writing a class it sometimes happens that you have to write a method which invokes methods of the same instance. I was wondering how to test those methods in isolation. Here is an abstract example demonstrating the problem: Class XYZ
  • method doThisIfCase1OrThatOtherwise
  • method doThis
  • method doThat
Testing doThis and doThat should not be a problem. But testing doThisIfCase1OrThatOtherwise without testing doThis and doThat again seemed impossible to me. Of course it would be possible to extract doThis and doThat into a separate class and then mock this class when testing doThisIfCase1OrThatOtherwise. But there are cases doing this smells a bit like over engineering. In cases I don't know what to do I ask Misko my test and clean code oracle. As always he provided me with a solution: Override the methods doThis and doThat and assert that they get called. This is an example from my "real" world: The class under test:
...
public void openAndCreateIfNotExists() throws IOException {
if (!destinationClassPathFile.exists()) {
 createEmptyClassPathFile();
} else {
 openExistingClassPathFile();
}
}

void createEmptyClassPathFile() {
eclipseClassPathDocument = DocumentHelper.createDocument();
eclipseClassPathDocument.addElement("classpath");
}

void openExistingClassPathFile() throws IOException {
SAXReader reader = new SAXReader();
try {
 eclipseClassPathDocument = reader.read(destinationClassPathFile);
} catch (DocumentException e) {
 throw new IOException("Invalid class path file " + destinationClassPathFile.getCanonicalPath(), e);
}
}
...
The test:
@Test
public void testOpenAndCreateIfNotExistsCreates() throws IOException {
File file = new File("src-test/testOpenAndCreateIfNotExistsCreates.testFile");
if (file.exists())
 file.delete();
file.deleteOnExit();
assertFalse(file.exists());
final StringBuilder stringBuilder = new StringBuilder();
EclipseClassPathManipulator eclipseClassPathManipulator = new EclipseClassPathManipulator(file) {
 @Override
 void createEmptyClassPathFile() {
  stringBuilder.append("igotcalled");
 }
};
eclipseClassPathManipulator.openAndCreateIfNotExists();
assertEquals("igotcalled", stringBuilder.toString());
}

@Test
public void testOpenAndCreateIfNotExistsOpens() throws IOException {
final StringBuilder stringBuilder = new StringBuilder();
File file = new File("src-test/testOpenAndCreateIfNotExistsOpens.testFile");
file.createNewFile();
file.deleteOnExit();
assertTrue(file.exists());
EclipseClassPathManipulator eclipseClassPathManipulator = new EclipseClassPathManipulator(file) {
 @Override
 void openExistingClassPathFile() throws IOException {
  stringBuilder.append("igotcalled");
 }
};
eclipseClassPathManipulator.openAndCreateIfNotExists();
assertEquals("igotcalled", stringBuilder.toString());
}

Mittwoch, 17. Juni 2009

java.io.FileFilter - a pragmatic and powerful way to select files

Today I discovered the FileFilter interface. A little bit late maybe - but better late than never!
File[] libs = libDir.listFiles(new FileFilter() {
  public boolean accept(File pathname) {
     return !pathname.isDirectory() && pathname.getName().endsWith(".jar");
  }
});
This example is a very simple one but since this is a method instead of a pattern like *.jar there are no limitations how the filtering is done. Regular expressions, web services, databases, relations of file names, ... I do like that approach since even it is powerful it's still simple and easy to use. If all API's were designed like this software development would be simpler and faster.

Dienstag, 2. Juni 2009

Providing user specific style sheets (using Stripes)

Customers often want to have a web application in their own CI. Stripes doesn't ship with a ready to use solution for this problem - but that would be impossible since every application has its own requirements for such a feature. But Stripes ships with a feature called user friendly urls. IMHO there are a lot of other web frameworks providing this feature so the following solution is not strictly tied the Stripes framework. The main idea behind this is to include standard css files in a common way:
<link rel="stylesheet" type="text/css" href="/css/ci.css">
and override special style definitions with user specific ones:
<link rel="stylesheet" type="text/css" href="/user-styles/css/ci.css">
The folder css is a real existing one. The folder user-styles is an action bean bound to the url /user-styles/ with a default handler method. The part after /user-styles(/css/default.css) is mapped to a property called "requestedFile". The default handler now builds a real path in some way like this: "<userSpecificStyleFolder>/<userId>/requestedFile" Then the default handler loads this file using the real path(java.nio provides a fast way to read files) and streams it out. If all the images are defined in the css files using a relative path, these images will also be requested using the default handler. So even user specific images are supported. If the users are organized in companies a company wide style could be achieved if the userId is replaced with the companyId when building the real path("<userSpecificStyleFolder>/<companyId>/requestedFile"). In Stripes the action bean would look like this:
@StrictBinding
@UrlBinding("/user-styles/{requestedFile}")
public class UserStyleAction implements ActionBean {
 private static final Log log = LogFactory.getLog(UserStyleAction.class);
 static final String FILE_SEPARATOR = System.getProperty("file.separator");
 private ActionBeanContext actionBeanContext;
 private String requestedFile;
 private String basePath;
 private User user;

 public UserStyleAction() {}

 public UserStyleAction(String basePath) {
  this.basePath = basePath;
 }

 @Before(on="serveFile")
 public Resolution loadUserFromSessionAndSendErrorIfNotLoggedIn() {
  user = (User) actionBeanContext.getRequest().getSession().getAttribute(User.class.toString());
  if (user == null)
   return new ErrorResolution(404);
  return null;
 }

 @Before
 public void initBasePath() throws IOException {
  // This is done to make this project run in every eclipse --> use a config
  // file in real world apps
  String realPathOfClass = actionBeanContext.getServletContext().getRealPath("UserStyleAction.class");
  String webAppFolder = realPathOfClass.replace("UserStyleAction.class", "");
  basePath = new File(webAppFolder + FILE_SEPARATOR + "WEB-INF" + FILE_SEPARATOR + "user-styles").getCanonicalPath();
 }

 @DefaultHandler
 public Resolution serveFile() throws IOException {
  try {
   String mimeType = actionBeanContext.getServletContext().getMimeType(requestedFile);
   File file = new File(buildAbsoluteFilePath(basePath, user));
   throwExceptionInCaseOfDirectoryTraversalAttack(basePath, file);
   FileInputStream fileInputStream = new FileInputStream(file);
   StreamingResolution streamingResolution = new StreamingResolution(mimeType, fileInputStream);
   return streamingResolution;
  } catch (Exception e) {
   if (log.isDebugEnabled())
    log.debug("Error reading file " + requestedFile + " requested by user " + user, e);
   return new ErrorResolution(404);
  }
 }

 String buildAbsoluteFilePath(String basePath, User user) {
  return basePath + FILE_SEPARATOR + user.getId() + FILE_SEPARATOR + requestedFile;
 }

 void throwExceptionInCaseOfDirectoryTraversalAttack(String basePath, File file) throws IOException {
  if (!file.getCanonicalPath().startsWith(basePath + FILE_SEPARATOR + user.getId()))
   throw new RuntimeException("Attempt to hack the application");
 }

 @Validate
 public void setRequestedFile(String requestedFile) {
  this.requestedFile = requestedFile;
 }

 @Override
 public ActionBeanContext getContext() {
  return actionBeanContext;
 }

 @Override
 public void setContext(ActionBeanContext context) {
  this.actionBeanContext = context;
 }

}
A full sample is available at the svn repository

Sonntag, 31. Mai 2009

The future of the human race

This science fiction future theory differs from the golden future theories of movies like Star Trek. It predicts no nuclear war but is more frightening than Terminator or The Chronicles of Riddick. Its theory seems also more presumably than the other ones: via videosift.com

  © Blogger template 'Morning Drink' by Ourblogtemplates.com 2008

Back to TOP