openengine

Derailed in Uncle Gates' Victory Garden.




Running Tomcat 5.5 in Remote Debug Mode with Java 5 (Jdk 1.5.0_6)

0 comments

Today I've been trying to run Tomcat 5.5 in jpda mode with Java 5. It seems that the catalina.bat/catalina.sh is shipped with a small error in v5.5 in that you need to add the arguments:

These are the orginal lines 98-106 in my catalina.bat


if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_shmem
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=jdbconn
:gotJpdaAddress
shift
:noJpda


The instructions I had were to change the SET JPDA_ADDRESS and SET JPDA_TRANSPORT lines to:


...
set JPDA_TRANSPORT=dt_socket
...
set JPDA_ADDRESS=8000
...


But in fact what I had to specify was;


if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_socket
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=address=8000,server=y
:gotJpdaAddress
shift


The extra address= and server= are required with Java 5.



If anyone has experienced the below error using a combination of Spring MVC and Tomcat, the way to get around it is to exclude the jsp-api.jar. In my case this was jsp-api-2.0.jar.


org.apache.jasper.JasperException: /markup/template/exception/page.jsp(6,0) Failed to load or instantiate TagExtraInfo class: org.apache.struts.taglib.tiles.UseAttributeTei
org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:39)
org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:405)
org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:86)
org.apache.jasper.compiler.Parser.processIncludeDirective(Parser.java:339)
org.apache.jasper.compiler.Parser.parseIncludeDirective(Parser.java:372)
org.apache.jasper.compiler.Parser.parseDirective(Parser.java:475)
org.apache.jasper.compiler.Parser.parseElements(Parser.java:1543)
org.apache.jasper.compiler.Parser.parse(Parser.java:126)
org.apache.jasper.compiler.ParserController.doParse(ParserController.java:211)
org.apache.jasper.compiler.ParserController.parse(ParserController.java:100)
org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:146)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:293)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:97)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:961)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:738)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:658)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:392)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:347)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)




Resetting root password in SUSE 10.0: A lesson for the foolish

0 comments

For the last couple of months, I've been performing an experiment involving my parents and linux. I wanted to test if the distros had moved on far enough to allow people who are not just lacking in confidence with PC's but damned right scared of them. So Mum and Dads old PC exploded and I decided to see how they would fair.

I opted for SUSE linux because it was the most friendly, and in their defence they have been fairing very well, considering it is all completely new.

I however have failed less well. Needless to say, in some manner I lost the root password of their system. So installing a printer last weekend suddenly became quite a big headache.

I wrote up this entry to save anyone who may befall my fate in the future. NB You still need to know a password on the system, just a normal user will do.

To reset the root password in SUSE 10.0:

- Boot to the SUSE skin on grub (the boot screen)
- Press F2 for more options
(it then gives you the option to enter in custom kernel options)
- type "init=/bin/bash" into the text box.
- then press enter

This will boot you to a very low boot level (below init 1). You won't even have your hard disk mounted.

- mount the hard disk by creating a dir in /mnt/ to mount it too, ex hddrive (cd /mnt; mkdir hddrive)
- mount command I used was:
mount -o rw /dev/hda3 /mnt/hddrive

- then vi or pico into the /etc/shadow file
- Copy the value of the password hash of the user that you know the password over the password hash of the root user, this should be in the 2nd or 3rd colon separated column. see below starting 6

chris:1:671jkdhaksudh8391723982312hjkasdasd: ....


- there are quite a few columns after this, leave these intact.
- then reboot
- You should be able to login as root with your known password.

WARNING: SUSE doesn't allow the root password to have a null set, if you try removing the entire password you will get wierd results.

I hope this knowledge helps someone save the 4-5 hours it took me.







Deep Logging Using Spring and AOP (SMEG)

0 comments

For sometime I've been thinking about open sourcing a small piece of Java code I wrote that makes the analysis of sub components of a system at runtime easier. My requirement was to create a piece of code which can tell me how the separate libraries of the services I was working on at the time were behaving at runtime. Was LibA running very slowly, was LibB throwing exceptions that were being muffled higher up the chain? So to meet this need I wrote SMEG.

The code for SMEG is broken into 2 parts, the first is an AOP interceptor that you wrap around particular components in a system. This interceptor doesn't do anything fancy, it just generates an event from the application context and then carries on execution.

The second part of the system is a listener for these events. In theory you could do anything you what with these events, in practice what I've done is capture these events and formulate a fake stack from them giving the percentage of the total execution time of each wrapped sub component.

What does this mean to me, I hear you lament? Well, for example say I have a service called the AeroplaneService. This service is a way of exposing on the wire a bunch of macro functionality of an aeroplane. Some of the operations on my service could be:


package org.openengine.service.aerplane;

public interface AeroplaneService {
public void takeOff() throws AeroPlaneException;
public void land() throws AeroPlaneException;
}


These operations represent quite coarse grained operations, there is a lot of things going on when a plane takes off. In reality what would happen is these methods would delegate to other services. Some examples of these services might be:



public interface LandingGearService {
public void liftUp() throws AeroPlaneException;
public void lower() throws AeroPlaneException;
}

public interface AeroplaneEngineService {
public void increaseThrottle() throws AeroPlaneException;
public void decreaseThrottle() throws AeroPlaneException;
}


Now if I wanted to inspect the running of a plane during flight, I could write logging statements throughout the code to say something like "BEFORE: liftUp() time=12:51:54pm" and "AFTER: liftUp() time=12:51:58pm". And then I could extrapolate from this the time required to perform the lift up operation. But this feels invasive, lots of code statements around clogging up business logic, lots of post processing to get anything meaningful. Ideally what I'd like is a way to record this information in a way that has no impact on my code, that can be turned off and on in config and that gives me the running cost of the liftUp method on the LandingGearService as a percentage of the total of the AeroplaneServices takeOff() method. This is what SMEG was designed to do.

So what we do is wrap our AOP interceptor around the AeroplaneService, the LandingGearService and the AeroplaneEngineService. The in the background SMEG captures the events being generated and records them against a thread, pairing the start of a method with its completion and then writing out the result to a log file.

So what we end up with is a log like this:


2006-02-24 11:36:30,716|[Thread-1]|020.00|ms|100.00%|d=0|s=2|AeroplaneService.takeOff() : void
2006-02-24 11:36:30,716|[Thread-1]|010.00|ms|050.00%|d=1|s=1| LandingGearService.liftUp() : void
2006-02-24 11:36:30,716|[Thread-1]|010.00|ms|050.00%|d=1|s=0| AeroplaneEngineService.increaseThrottle() : void


We can see from this that inside of the AeroplaneService.takeOff() method we executed two methods on our other wrapped interfaces, AeroplaneEngineService.increaseThrottle() and LandingGearService.liftUp(), each one took 50% of the time of the call to execute and in real terms the time was 10 ms each.

This allows you to produce simple runtime statistics for your system without having to trawl through your code writing start and stop log statements.

Please watch this space and openengine.org for when SMEG becomes available.

Chris


First Test for Blog

2 comments

1st blog for open engine



c:\>test.exe


About me

  • I'm Chris Stevenson
  • From London

Last posts

Archives

Links


ATOM 0.3