Current development on JAMWiki is primarily focused on maintenance rather than new features due to a lack of developer availability. If you are interested in working on JAMWiki please join the jamwiki-devel mailing list.

Bug Reports/Resolved/0.7.x

This page is an archive of Bug Reports resolved during the JAMWiki 0.7.x release cycle. See Bug Reports/Resolved for an index of all resolved bug reports.

Contents

Whitespace Collapses Paragraphs

JAMWiki 0.6.7

text(return)
(return)
text(return)

Correctly displays as

text
text

But if the whitespace is added.

text(return)
(whitespace)(return)
text(return)

It displays as

text text

In the first case there are three paragraph tags, in the second case only one. It should render with two tags in both cases to mimic MediaWiki. j_teer 06-Jan-2009 12:24 PST

You can compare here http://www.mediawiki.org/wiki/Sandbox . What may be happening is that JAMWiki is considering whitespace as content. I am not sure if either MediaWiki or JAMWiki is implemented correctly in this case. j_teer 06-Jan-2009 18:15 PST
I think the single space is being seen as pre-formatted text. I've had a ton of problems getting paragraph parsing exactly right, but will create a test case for this condition and look into it further. -- Ryan 06-Jan-2009 19:37 PST
revision 2414 adds a unit test (disabled) for this test case. -- Ryan 06-Jan-2009 20:19 PST
Thanks Ryan, it's not a high priority but I know you wanted to exactly mimic MediaWiki parsing so I mentioned it. j_teer 07-Jan-2009 11:37 PST
The unit test is very much appreciated. I did a major round of parser cleanups for the JAMWiki 0.6.6 release, and will undoubtedly be doing further cleanups in future releases. Having these test cases is a great way to keep track of what still needs to be done to improve Mediawiki compatibility, so the more the better. The only downside is that it means that on some future Saturday I'll be sitting in front of the laptop rather than out climbing mountains or visiting the beach, but such is life :) -- Ryan 07-Jan-2009 12:14 PST
revision 2428 should resolve this issue. Thanks again for the report! -- Ryan • (comments) • 17-Jan-2009 13:38 PST

Response Committed Failure

2008-09-06 22:29:32,154 SEVERE: org.jamwiki.taglib.WatchlistTag - Failure processing watchlist item Sandbox
java.lang.IllegalStateException: Cannot create a session after the response has been committed
	at org.apache.catalina.connector.Request.doGetSession(Request.java:2214)
	at org.apache.catalina.connector.Request.getSession(Request.java:2024)
	at org.apache.catalina.connector.RequestFacade$GetSessionPrivilegedAction.run(RequestFacade.java:195)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:829)
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:215)
	at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:544)
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:215)
	at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:544)
	at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:493)
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:223)
	at org.jamwiki.servlets.ServletUtil.currentWatchlist(ServletUtil.java:346)
	at org.jamwiki.taglib.WatchlistTag.doStartTag(WatchlistTag.java:45)
	at org.apache.jsp.WEB_002dINF.jsp.recent_002dchanges_jsp._jspx_meth_jamwiki_watchlist_0(recent_002dchanges_jsp.java:1137)

Seen occasionally on Special:RecentChanges after pushing the latest 0.7.0 code to jamwiki.org. -- Ryan 06-Sep-2008 22:46 PDT

revision 2295 may resolve this issue. -- Ryan 07-Sep-2008 21:08 PDT

Test Virtual Wiki in Release

Moved from the Feedback page:

In the web.xml file there is a servlet mapping for a test wiki. It doesn't show up in the virtual wiki list. The entry should probably be removed.

Thanks for catching that. revision 2406 removes it. -- Ryan 02-Jan-2009 15:29 PST

log4j warning

JAMWiki 0.6.7

On application startup there is a warning from log4j in stdout that says it could not find an appender. This may be because there is not a log4j.properties file and commons logging is configuring after the fact. j_teer 06-Jan-2009 17:55 PST

JAMWiki isn't configured to use log4j, and log4j isn't included in the default distribution. Is it possible you've got classpath issues? Alternatively, have there been any modifications made that would pull in log4j? -- Ryan 06-Jan-2009 19:35 PST
log4j is in the JAMWiki 0.6.7 war distribution under WEB-INF/lib. I haven't looked closely at the project pom but it may be an indirect dependency and is slipping in by accident. I believe commons logging also attempts to use log4j by default before dropping back to another logging implementation. j_teer 07-Jan-2009 17:30 PST
You're right, I was looking at the latest (Subversion) code, which doesn't include log4j in the generated WAR file. Perhaps the old Acegi code was pulling it in as a Maven dependency? In any case, log4j does not seem to be included with builds of 0.7.0, so hopefully this will no longer be an issue. -- Ryan 07-Jan-2009 18:19 PST

Alignment of radio buttons in History page

mediawiki-history.jpg
Screenshot of the Mediawiki history UI

The radio buttons seem to be not properly aligned in the History page. Two columns of radio buttons are appearing in the History page.

--yesesnono 02-Dec-2008 04:29 PST

The UI for the history page was changed to match Mediawiki (see the image) - is that what you're seeing, or is there something else? As far as I'm aware this change is working as expected, but please let me know if you are seeing something different. -- Ryan 02-Dec-2008 20:05 PST
The UI is appearing the same as in the screenshot. thank you for your explanation. --yesesnono 03-Dec-2008 22:16 PST

logging.properties typo

JAMWiki 0.6.7

The line 'The default level for the Handler. See the Javadoc for the java.util.Level class for valid values.' It should read java.util.logging.Level instead of java.util.Level.

j_teer 06-Jan-2009 14:34 PST

revision 2415 resolves this issue. Thanks for the report. -- Ryan 07-Jan-2009 20:35 PST

Default Log Level

JAMWiki 0.6.7

By default the log level set by logging.properties is CONFIG which includes INFO. Each time a page is loaded the page parse time is logged to the application server's stdout. This is by default not needed. The level should be set to WARN.

j_teer 06-Jan-2009 14:34 PST

revision 2415 resolves this issue. Thanks for the report. -- Ryan 07-Jan-2009 20:35 PST

Add link support that points to a Windows shared folder

Not sure is this a bug or a feature request, so I list here anyway.

I can use file://\\shared\docs, but it only seems to work on IE.

I'm not sure that this is a JAMWiki issue - does the same link work when you paste it into the URL bar in Firefox? My guess is that Firefox won't support Windows shared drives as URL links, although I could definitely be wrong. -- Ryan • (comments) • 13-Jan-2009 07:52 PST
A backslash is an invalid URL character. IE accepts it so it's compatible with Windows using backslashes in the file system. Firefox want's you to use forward slashes. The following should work on both. j_teer 13-Jan-2009 14:01 PST
file://///shared/docs/

Misleading documentation and admin pages regarding LDAP integration

Jamwiki-0.6.6: The entire documentation still refers to the org.jamwiki.ldap.LdapUserHandler approach. This is also the case for the Jamwiki properties file and the Admin pages. However this approach does not seem to work (at all?) anymore in Jamwiki-0.6.6 since you moved to the acegi solution. Please highlight this fact more prominently so that people know directly that they must hack spring XML config files for the time being... Thanx!

I don't think anything changed with 0.6.6 for LDAP, although the current Subversion code for the 0.7.0 release contains significant Acegi changes. I don't use LDAP personally (which is why it's still marked "experimental"), although there have been success reports from some users. What problems are you seeing? -- Ryan 17-Jul-2008 20:36 PDT

I changed the configuration in jamwiki.properties so that the system would use the LdapUserHandler. However, the LdapUserHandler code never got called (checked via debugger). Essentially logging in was turned off then. After some fiddeling around, I noticed that authorization is handled entirely via spring beans configured in applicationContext-agegi-security.xml. The hook in that file is here:

	<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
		<property name="providers">
			<list>
				<ref local="daoAuthenticationProvider" />
				<ref local="ldapAuthenticationProvider" /> <!-- <<<--- got to start with config here.. -->
				<ref local="anonymousAuthenticationProvider" />
				<ref local="rememberMeAuthenticationProvider" />
			</list>
		</property>
	</bean>

After some configuration and downloading the acegi sources, I got it to work.

Note that I am new to Jamwiki - so it could well be that I have overlooked something. Anyway, I like the project so far - it is well engineered. It is still small and clean enough so that I can work my way through (as it seems). It is also pretty fast compared to other Wiki's. Daniel

There isn't really any documentation for LDAP, so you're doing everything as right as could be expected. Currently the Special:Admin screen contains some options for setting up LDAP authentication, but only for validating login/password. A few people have configured Acegi for more advanced LDAP functionality, and my hope is that the next release will make LDAP setup considerably simpler with the transition to Acegi 2.0. Also, thanks for the kind words for the project! -- Ryan 20-Jul-2008 20:38 PDT
Closing this bug as Spring Security 2.0 supercedes the LDAP configuration used in previous versions. -- Ryan • (comments) • 24-Feb-2009 20:25 PST

Magic words not resolved in template reference

Magic words in template reference are not resolved to the corresponding value. When using a template reference like Template:Yearoverview2014 the resulting template name should be Template:yearoverview2007.

Yikes - I'll need to verify that Mediawiki supports using a magic word as part of a template name, and if so I'll investigate how difficult that functionality would be to implement for JAMWiki. Thanks for the report. -- Ryan 31-Dec-2007 18:29 PST
I think there might also be an issue with nested magic-words. The statement {{fullurl:{{FULLPAGENAME}}|action=edit}} should create an "edit"-link to the current page, according to the Mediawiki documentation. In JamWiki it creates a link to the article {{FULLPAGENAME}} instead. Henrik Sorensen, January 17th 2009
Magic word support in JAMWiki isn't as advanced as what Mediawiki offers (yet), so nesting them probably won't work. I've been meaning to revisit this functionality for some time now, so time permitting I may look into the code again over this long weekend. -- Ryan • (comments) • 17-Jan-2009 14:01 PST
Thanks for your quick reply and your work on JamWiki. Henrik Sorensen
revision 2439 adds (minimal) support for the basic Mediawiki parser functions. Nesting still doesn't work, and pipe-delimited arguments such as {{fullurl:Bug Reports|nowiki}} are not yet supported, but I'll get to that soon. Supported functions are {{anchorencode:}}, {{filepath:}}, {{fullurl:}}, {{localurl:}} and {{urlencode:}}.
...and now revision 2443 adds support for nested templates. Support for adding parser function arguments is still on the to-do list. -- Ryan • (comments) • 19-Jan-2009 21:50 PST
Support for parser function arguments was added in revision 2451. The specific URL indicated above - {{fullurl:{{FULLPAGENAME}}|action=edit}} - still won't link to an edit page due to differences between Mediawiki's link syntax and JAMWiki's but it will resolve properly - http://jamwiki.org/wiki/en/Bug_Reports/Resolved/0.7.x?action=edit. -- Ryan • (comments) • 31-Jan-2009 20:43 PST

Changing title text

Greetings, I have a local installation, the title for each page is: <topic name> - JAMWIKI. Would it be possible to rename that to: <Title page> - Company Knowledge Base ? 167.193.84.7 31-Jan-2008 08:39 PST

Hi - using the Special:Translation tool you can change the key for "common.sitename" and that should solve the issue. You will need to restart your application server after changing any translation. Longer term it probably makes sense to make this something that can be configured in a more obvious way, so I'll keep this open and (hopefully!) address it in a future release. -- Ryan 31-Jan-2008 08:46 PST

LDAP Integration via acegi-security

After some time I finally got Authentication via Active Directory and acegi-security working. With org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator I can set the defaultRole to ROLE_USER, so TabMenu and UserMenu are displayed. But after logon, there are several Problems with that Authentication:

  1. Special:Account is available, but Password and Login cannot be changed.
  2. The Link to the Users Page leads to Special:Edit?topic=User:null and is displayed with null
  3. There is no Link to Special:Edit on the pages created at setup (eg. StartingPoints)
  4. Special:Watchlist leads of course to an exception (Failure while executing insert into jam_watchlist ( virtual_wiki_id, topic_name, wiki_user_id ) values ( ?, ?, ? ))

Are there any hints or work-arounds for these issues? I think it would be possible (not really beautiful) to insert a wiki_user_id for each LDAP-uid. Is there another possibility?

-- hp 11-Mar-2008 10:38

Thanks for digging into this. I'm sure that any issues you're hitting are bugs in JAMWiki since LDAP integration is not well tested - I suspect that there is a bug in WikiUser initialization that is causing a failure of LDAP roles to be copied into the user object - I can dig into that and try to put a fix together if you're willing to help debug more. I think that this will probably solve 2, 3, and 4 above, but allowing updates to the LDAP password will probably be more involved and may something for someone more knowledgeable about LDAP to investigate. -- Ryan 11-Mar-2008 08:02 PDT
I haven't looked at this code in a while, so it took some digging, but it looks like full LDAP integration via Acegi probably isn't going to work at this time without a lot of updates to the code. What is happening is that the JAMWikiDaoImpl.loadUserByUsername() method is calling the WikiUserAuth constructor, which then loads the default permissions. Unfortunately, those permissions are expected to be in JAMWiki's role table. Thus, it is possible to use LDAP to validate login / password, but it doesn't look like it is possible to use LDAP for role retrieval at the moment.
The original Acegi integration was done as sort of a hybrid - the original (custom) login code was kept, and Acegi was then put on top of it. Rainers did a great job, but when Acegi 2.0 comes out (they just released 2.0-M2) my hope was that the Acegi integration could be completely re-done to take full advantage of that framework, allowing for full LDAP integration, captcha support, etc. If you're interested in helping it would be great to have someone with solid LDAP experience on board, although it's also been great to have your feedback thus far on an aspect of JAMWiki that isn't widely used. -- Ryan 11-Mar-2008 21:23 PDT
I'd be interested in helping with both, LDAP/Acegi and MSSQL-support, these features are quite important for me. If you could add my sf-id (hanspeterklapf) to the project, I would be able to test the latest branch of JAMWiki in our Environment (ActiveDirectory, MSSQL 2005). --hp 13-Mar-2008 05:23 PDT
Done - let me know if you encounter any Subversion errors. I'll probably be pushing a new release this weekend to resolve a JSP issue that breaks the Special:Manage page, so if you make any commits to trunk during the next couple of days please just make sure that they are of the "obviously correct" variety, but after the 0.6.5 release goes out the trunk will be open to more extensive changes, and you're of course always welcome to create your own branch. Thanks for offering to investigate - the LDAP code is definitely in need of attention, and MS SQL support may have bitrotted somewhat due to the fact that I don't have access to a MS SQL server and there aren't a lot of JAMWiki users who utilize that database. -- Ryan 13-Mar-2008 08:09 PDT
Closing this bug report as Spring Security 2.0 supercedes the old LDAP support. -- Ryan • (comments) • 24-Feb-2009 20:25 PST

#REDIRECT

Moved from the Feedback page:

I'd like to redirect one of my pages to another one using the following code


#REDIRECT [[MyOtherPage]]

[[Category:Glossary]]

This results in


   1. REDIRECT MyOtherPage

+----------------------+
| Categories: Glossary |
+----------------------+

--Sil68 02-Apr-2008 23:59 PDT

I never realized that a #REDIRECT page could have any other content - I'll have to take a look at this to see how difficult it will be to implement. It may not make it into JAMWiki immediately, but will definitely get in eventually. Thanks for pointing it out. -- Ryan 03-Apr-2008 20:15 PDT

From james_battersby@hotmail.com 05-Dec-2008 16:37 GMT

In MediaWiki apparently it is possible to have redirects belonging to a category. The idea is that although a page will immediately redirect to another, the redirect page will appear in Category listings so long as you place the REDIRECT and [[Category:x]] on the same line. Have a look at http://www.scottdstrader.com/blog/ether_archives/000329.html for a better explanation (look for How to add categories to redirects).

I recently fell over this bug too. This is a deviation from the MediaWiki behaviour. As users normally do not see the contents of a redirect page, IMHO this is no serious issue.
As a circumvention to the "redirect page in a category" issue one could put two category tags for the same category...
Kind regards Rudi Wiesmayr (AT) 24-Jan-2009 11:55 PST
Thanks for the additional confirmation - it helps let me know what issues are important to people. Time permitting I'll take another look at this one and see how feasible it is to fix for an upcoming release. If it can't be fixed I'll see if I can at least get a unit test in place for it so that it gets a bit more visibility. -- Ryan • (comments) • 24-Jan-2009 23:22 PST
The code is ugly, but revision 2446 adds support for categories on redirect pages. I haven't yet pushed the new code to jamwiki.org, but it will be available as part of the 0.7.0 release. -- Ryan • (comments) • 26-Jan-2009 20:04 PST
revision 2447 cleans up the code for this functionality and adds some unit tests. The new code will probably get pushed to jamwiki.org this weekend after I've had time to do a bit more testing. -- Ryan • (comments) • 27-Jan-2009 21:59 PST

Many ImageUtils bugs and fixes

Hi, I hope you are enjoying your holiday! I have been looking into ImageUtil in a lot more detail as someone on my wiki created a page with 50 3MB images that are all resized, and it made my JVM memory usage shoot up, my CPU usage spike every time the page was requested, and I was seeing a 45 second parser time which was insane!

After looking into it in detail, I noticed that to get the image resolution information, the entire image is read into memory. When a resized image is requested, this operation is performed two or even three times, which is a massive waste of resources so I did the following to fix this...

http://schmidt.devlib.org/image-info/index.html contains a very clever public domain class that will only read in the bit of an image it needs to learn the resolution. I converted almost all reads of image information from BufferedImage to this ImageInfo class and saw a massive speed boost. In LinkUtil, I made sure that any WikiImage handling did not assume that there was a value for height and width (so height and width are no longer used for many images), as this meant I could use resized images based on the filename and if the file exists, rather than having to read in and analyse one every time it was loaded. I also made sure that no images were being read if the only reason to read them was to return a height and width to the img tag as this is a waste of server resources and the client can handle it instead (though the code is there but commented if you feel the small increase in page rendering time is worth it - I have third party adverts on my wiki so it makes no difference to render time for me).

Making these changes allowed me to go from a 45 second render time to a 0.2 second render time on the image heavy page, and there has been a massive improvement on every page that has an image. I highly recommend you test this a bit and then implement the changes!

My ImageUtil class now looks like this (based on my local fork of 0.6.2):

public class ImageUtil {

	private static final WikiLogger logger = WikiLogger.getLogger(ImageUtil.class.getName());
	private static final String CACHE_IMAGES = "org.jamwiki.utils.ImageUtils.CACHE_IMAGES";

	/**
	 *
	 */
	private ImageUtil() {
	}

	/**
	 *
	 */
	private static int calculateImageIncrement(int maxDimension) {
		int increment = Environment.getIntValue(Environment.PROP_IMAGE_RESIZE_INCREMENT);
		double result = Math.ceil((double)maxDimension / (double)increment) * increment;
		return (int)result;
	}

	/**
	 * Convert a Java Image object to a Java BufferedImage object.
	 */
	private static BufferedImage imageToBufferedImage(Image image) throws Exception {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB );
		Graphics2D graphics = bufferedImage.createGraphics();
		graphics.drawImage(image, 0, 0, null);
		graphics.dispose();
		return bufferedImage;
	}

	/**
	 * Given a virtualWiki and WikiFIle that correspond to an existing image,
	 * return the WikiImage object.  In addition, an optional maxDimension
	 * parameter may be specified, in which case a resized version of the image
	 * may be created.
	 *
	 * @param wikiFile Given a WikiFile object, use it to initialize a
	 *  WikiImage object.
	 * @param maxDimension The maximum width or height for the initialized
	 *  WikiImage object.  Setting this value to 0 or less will cause the
	 *  value to be ignored.
	 * @return An initialized WikiImage object.
	 * @throws Exception Thrown if an error occurs while initializing the
	 *  WikiImage object.
	 */
	public static WikiImage initializeImage(WikiFile wikiFile, int maxDimension) throws Exception {
		if (wikiFile == null) {
			logger.warning("No image found for " + wikiFile.getVirtualWiki() + " / " + wikiFile.getFileName());
			return null;
		}
		WikiImage wikiImage = new WikiImage(wikiFile);
		ImageInfo originalInfo = null;
		// do some processing if a resized image is requested, otherwise just return the base image converted to a WikiImage...
		if (maxDimension > 0) {
			originalInfo = ImageUtil.resizeImage(wikiImage, maxDimension);
			if (originalInfo!=null) setScaledDimensions(originalInfo, wikiImage, maxDimension);
		}
		return wikiImage;
	}

	/**
	 * Given a File object, determine if the file is an image or if it is some
	 * other type of file.  Note that this method will read in the entire file,
	 * so there are performance implications for large files.
	 *
	 * @param file The File object for the file that is being examined.
	 * @return Returns <code>true</code> if the file is an image object.
	 * @throws Exception Thrown if any error occurs while reading the file.
	 */
	public static boolean isImage(File file) throws Exception {
		return (ImageUtil.loadImage(file) != null);
	}

	/**
	 * Get an image info object so we can get the resolution of an image efficiently.
	 */
	private static ImageInfo getImageInfo(File imageFile) throws Exception {
		java.io.FileInputStream fis = new java.io.FileInputStream(imageFile);
		ImageInfo originalInfo = null;
		originalInfo.setInput(fis);
		if (!originalInfo.check()) throw new Exception("File not found or error reading file."); // image reading error
		return originalInfo;
	}

	/**
	 * Given a file that corresponds to an existing image, return a
	 * BufferedImage object.
	 */
	private static BufferedImage loadImage(File file) throws Exception {
		return ImageIO.read(file);
	}

	/**
	 * Resize an image, using a maximum dimension value.  Image dimensions will
	 * be constrained so that the proportions are the same, but neither the width
	 * or height exceeds the value specified.
	 */
	private static ImageInfo resizeImage(WikiImage wikiImage, int maxDimension) throws Exception {
		// first test to see if an image with maxDimension has already been created, if so just return it to save time and effort...
		ImageInfo originalInfo = null;
		String newUrl = wikiImage.getUrl();
		int pos = newUrl.lastIndexOf('.');
		if (pos > -1) {
			newUrl = newUrl.substring(0, pos) + "-" + maxDimension + "px" + newUrl.substring(pos);
		} else {
			newUrl += "-" + maxDimension + "px";
		}
		File newImageFile = new File(Environment.getValue(Environment.PROP_FILE_DIR_FULL_PATH), newUrl);
		if (newImageFile.exists()) {
			// if we want to send back height and width for the img tag to be drawn faster, we would uncomment this at a cost of higher memory, disk and CPU usage.
			//originalInfo.setInput(new java.io.FileInputStream(newImageFile));
			//if (!originalInfo.check()) throw new Exception("File not found or error reading file."); // image reading error
			wikiImage.setUrl(newUrl);
			return originalInfo;
		}

		// if we dont have the above, matching image, then create a new one if applicable...
		File imageFile = new File(Environment.getValue(Environment.PROP_FILE_DIR_FULL_PATH), wikiImage.getUrl());
		java.io.FileInputStream fis = new java.io.FileInputStream(imageFile);
		originalInfo = new ImageInfo();
		originalInfo.setInput(fis);
		maxDimension = calculateImageIncrement(maxDimension);
		int increment = Environment.getIntValue(Environment.PROP_IMAGE_RESIZE_INCREMENT);
		if (!originalInfo.check()) throw new Exception("File not found or error reading file."); // image reading error
		if (increment <= 0 || (maxDimension > originalInfo.getWidth() && maxDimension > originalInfo.getHeight())) {
			// let the browser scale the image
			return originalInfo;
		}
		int width = -1;
		int height = -1;
		if (originalInfo.getWidth() >= originalInfo.getHeight()) {
			width = maxDimension;
		} else {
			height = maxDimension;
		}

		Image resized = null;
		BufferedImage original = ImageUtil.loadImage(imageFile);
		try {
			resized = original.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
		} catch (Throwable t) {
			logger.severe("Unable to resize image.  This problem sometimes occurs due to dependencies between Java and X on UNIX systems.  Consider enabling an X server or setting the java.awt.headless parameter to true for your JVM.", t);
			resized = original;
		}
		BufferedImage bufferedImage = null;
		if (resized instanceof BufferedImage) {
			bufferedImage = (BufferedImage)resized;
		} else {
			bufferedImage = ImageUtil.imageToBufferedImage(resized);
		}
		ImageUtil.saveImage(bufferedImage, newImageFile);
		originalInfo.setInput(new java.io.FileInputStream(newImageFile));
		if (!originalInfo.check()) throw new Exception("File not found or error reading file."); // image reading error
		return originalInfo;
	}

	/**
	 * Save an image to a specified file.
	 */
	private static void saveImage(BufferedImage image, File file) throws Exception {
		String filename = file.getName();
		int pos = filename.lastIndexOf('.');
		if (pos == -1 || (pos + 1) >= filename.length()) {
			throw new Exception("Unknown image type " + filename);
		}
		String imageType = filename.substring(pos + 1);
		File imageFile = new File(file.getParent(), filename);
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(imageFile);
			ImageIO.write(image, imageType, fos);
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (Exception e) {}
			}
		}
	}

	/**
	 *
	 */
	private static void setScaledDimensions(ImageInfo imageInfo, WikiImage wikiImage, int maxDimension) {
		int width = imageInfo.getWidth();
		int height = imageInfo.getHeight();
		if (width >= height) {
			height = (int)Math.floor(((double)maxDimension / (double)width) * (double)height);
			width = maxDimension;
		} else {
			width = (int)Math.floor(((double)maxDimension / (double)height) * (double)width);
			height = maxDimension;
		}
		wikiImage.setWidth(width);
		wikiImage.setHeight(height);
	}
}
Hi Jim - thanks for investigating. You're the first person I've heard of to use 45MB of images on a single page. I won't have a chance to review this stuff for a while, but if you need Subversion commit access simply let me know your Sourceforge ID and I can set you up the next time I'm near a spot with internet access. Alternatively I'll look at your code more closely when I get home in mid-July and integrate it as best I can. -- Ryan 29-Jun-2008 12:36 PDT
revision 2290 implements caching of image dimensions, which speeds things up significantly in local testing. I tried switching to the ImageUtil class but didn't see any noticeably improvement while testing locally. There are further improvements that could be made - there is more that can be done with caching, and perhaps adding an option to drop width and height from rendered images (as you've suggested) would be something that could be investigated. Many thanks for your original suggestions, and apologies for taking so long to get around to them. -- Ryan 04-Sep-2008 22:22 PDT

Using REDIRECT to a virtual wiki

I'm using the Virtual Wiki feature and I wanted to add a REDIRECT to my user page on the virtual wiki to point back to my main wiki. When I add the redirect

#REDIRECT [[:en:User:tfschueller]]

The link shows up to a new page on the virtual wiki. I did some testing and I can not get a redirect to work to any page using the Virtual Wiki syntax. --Tom 21-Aug-2008 17:05 PDT

Thanks for the report - I'll see if this can be resolved for the next release. -- Ryan 21-Aug-2008 20:44 PDT
revision 2334 mostly implements this functionality, although the code probably needs some cleanup, and while the final URL goes to the correct topic on the virtual wiki the navigation structure still reflects the old virtual wiki. -- Ryan 30-Sep-2008 21:41 PDT
revision 2340 resolves the issue with the redirect target's virtual wiki navigation structure. Now all that's left is cleanup to make the code less messy. -- Ryan 01-Oct-2008 21:38 PDT

Unable to change password on jamwiki.org

After pushing the latest 0.7.0 development code to jamwiki.org I get "Invalid old password" whenever I try to change my old password. Changing passwords on my local instance works fine. -- Ryan 06-Sep-2008 12:07 PDT

If I create a new account on jamwiki.org then I'm able to change the password for that account, so this problem appears to be something specific to my account. -- Ryan 06-Sep-2008 12:13 PDT

Problem while setup of JAMWiki 0.7.0 (first run)

If you deploy a new build war an exception occurs:

java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
	org.springframework.security.providers.anonymous.AnonymousAuthenticationToken.<init>(AnonymousAuthenticationToken.java:54)
	org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:68)
	org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)

If you comment out the Spring Security Filter in the web.xml, everything works fine. You can set up the system.

	<filter>
		<filter-name>Spring Security Filter Chain Proxy</filter-name>
		<filter-class>org.springframework.security.util.FilterToBeanProxy</filter-class>
		<init-param>
			<param-name>targetClass</param-name>
			<param-value>org.springframework.security.util.FilterChainProxy</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>Spring Security Filter Chain Proxy</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>JAMWikiFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

But, if the initialization is done, this filter must comment in otherwise you cannot log in as an administrator. In the log an other exeption is shown:

2008-09-19 16:00:01,421 SEVERE: org.jamwiki.authentication.WikiUserAuth - Unable to retrieve default roles for GROUP_ANONYMOUS
java.lang.ClassNotFoundException: org.postgresql.Driver
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1360)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1206)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:169)
	at org.jamwiki.utils.Utilities.forName(Utilities.java:221)
	at org.jamwiki.db.LocalDataSource.<init>(LocalDataSource.java:45)
	at org.jamwiki.db.DatabaseConnection.configDataSource(DatabaseConnection.java:257)

Strange, isn't it?

Environment: Tomcat 6.0.16

Thanks for the report, and for the testing - there are unfortunately not a lot of people helping to test the latest development code. I think what's happening is that for the initial setup the authentication is explicitly suppressed since nothing has yet been setup, causing the filter to fail. Once the security filters are removed other code in the site breaks due to not having information that is expected to be present. I'm not sure when this broke - I may not have done a clean install of the latest code in a while - but it shouldn't be hard to fix. -- Ryan 19-Sep-2008 09:28 PDT

Hi Ryan, I recognized the same Error. Once in a while I do check out the source, build and look for my webtests ;-) Ok. I do have not to much time free ;-/. I did start the clean build with: mvn jetty:run-exploded my test failed. Id did check the jetty container in the browser (http://localhost:8080/jamwiki-war) I get:

HTTP ERROR: 500
 
Cannot pass null or empty values to constructor
 
RequestURI=/jamwiki-war/en/Special:Setup
Caused by:
 
java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
	at org.springframework.security.providers.anonymous.AnonymousAuthenticationToken.(AnonymousAuthenticationToken.java:54) 
	at org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:68)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:109)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at  org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:271)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
	at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
	at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:58)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:757)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:416)
	at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
	at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:502)
	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:826)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:523)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:377)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:497)
 
Powered by Jetty://SCHWERWIEGEND: Unable to retrieve default roles for GROUP_ANONYMOUS
java.lang.ClassNotFoundException: org.postgresql.Driver
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at org.codehaus.classworlds.RealmClassLoader.loadClassDirect(RealmClassLoader.java:195)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:255)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:274)
        at org.codehaus.classworlds.RealmClassLoader.loadClass(RealmClassLoader.java:214)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:375)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at org.jamwiki.utils.Utilities.forName(Utilities.java:221)
        at org.jamwiki.db.LocalDataSource.<init>(LocalDataSource.java:45)
        at org.jamwiki.db.DatabaseConnection.configDataSource(DatabaseConnection.java:257)
        at org.jamwiki.db.DatabaseConnection.getConnection(DatabaseConnection.java:240)
        at org.jamwiki.db.WikiPreparedStatement.executeQuery(WikiPreparedStatement.java:60)
        at org.jamwiki.db.AnsiQueryHandler.getRoleMapGroup(AnsiQueryHandler.java:392)
        at org.jamwiki.db.AnsiDataHandler.getRoleMapGroup(AnsiDataHandler.java:395)
        at org.jamwiki.authentication.WikiUserAuth.getAnonymousGroupRoles(WikiUserAuth.java:266)
        at org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:68)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:109)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:271)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
        at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
        at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:58)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:757)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:416)
        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
        at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:324)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:502)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:826)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:523)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:377)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:497)
2008-09-20 21:25:37.079::WARN:  /jamwiki-war/en/Special:Setup
java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor

log is:

SCHWERWIEGEND: Unable to retrieve default roles for GROUP_ANONYMOUS
java.lang.ClassNotFoundException: org.postgresql.Driver
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at org.codehaus.classworlds.RealmClassLoader.loadClassDirect(RealmClassLoader.java:195)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:255)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:274)
        at org.codehaus.classworlds.RealmClassLoader.loadClass(RealmClassLoader.java:214)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:375)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at org.jamwiki.utils.Utilities.forName(Utilities.java:221)
        at org.jamwiki.db.LocalDataSource.<init>(LocalDataSource.java:45)
        at org.jamwiki.db.DatabaseConnection.configDataSource(DatabaseConnection.java:257)
        at org.jamwiki.db.DatabaseConnection.getConnection(DatabaseConnection.java:240)
        at org.jamwiki.db.WikiPreparedStatement.executeQuery(WikiPreparedStatement.java:60)
        at org.jamwiki.db.AnsiQueryHandler.getRoleMapGroup(AnsiQueryHandler.java:392)
        at org.jamwiki.db.AnsiDataHandler.getRoleMapGroup(AnsiDataHandler.java:395)
        at org.jamwiki.authentication.WikiUserAuth.getAnonymousGroupRoles(WikiUserAuth.java:266)
        at org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:68)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:109)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:271)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
        at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
        at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:58)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:757)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:416)
        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
        at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:324)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:502)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:826)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:523)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:377)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:497)
2008-09-20 21:25:37.079::WARN:  /jamwiki-war/en/Special:Setup
java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor

mbert 20-Sep-2008 12:43 PDT

revision 2323 fixes this issue for me on my local machine. Let me know if you continue to see issues, and thanks again for the detailed bug reports. -- Ryan 22-Sep-2008 20:41 PDT

Hi Ryan, the webtests succeded, but:

INFO: Loaded page /jamwiki-war/en/Special:Account (0.186 s.)
23.09.2008 09:12:32 org.jamwiki.utils.WikiLogger severe
SCHWERWIEGEND: Servlet error
java.lang.IllegalArgumentException: Cannot encrypt a null or empty string
        at org.jamwiki.utils.Encryption.encrypt(Encryption.java:70)
        at org.jamwiki.db.DatabaseUserHandler.authenticate(DatabaseUserHandler.java:61)
        at org.jamwiki.servlets.RegisterServlet.validate(RegisterServlet.java:207)
        at org.jamwiki.servlets.RegisterServlet.register(RegisterServlet.java:113)
        at org.jamwiki.servlets.RegisterServlet.handleJAMWikiRequest(RegisterServlet.java:61)
        at org.jamwiki.servlets.JAMWikiServlet.handleRequestInternal(JAMWikiServlet.java:74)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1124)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:359)
        at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
        at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.jamwiki.authentication.JAMWikiExceptionTranslationFilter.doFilter(JAMWikiExceptionTranslationFilter.java:70)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:75)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:116)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:271)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
        at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
        at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
        at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
        at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:58)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:757)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:416)
        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
        at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:324)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:502)
        at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:840)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:657)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:377)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:497)
23.09.2008 09:12:49 org.jamwiki.utils.WikiLogger info
INFO: No virtual wiki found in URL: /jamwiki-war/
23.09.2008 09:12:49 org.jamwiki.utils.WikiLogger info
INFO: Parse time (parseHTML) for StartingPoints (0.038 s.)
23.09.2008 09:12:49 org.jamwiki.utils.WikiLogger info
INFO: Loaded page /jamwiki-war/en/StartingPoints (0.043 s.)
23.09.2008 09:12:49 org.jamwiki.utils.WikiLogger info
INFO: Loaded page /jamwiki-war/en/jamwiki.css (0.0020 s.)

So I'm not sure if everything is right. -- mbert 23-Sep-2008 03:01 PDT

Thanks for the additional report. How do I reproduce this issue? I've tried going to the Special:Account page as a logged-in user and as an anonymous user, but neither generates this stack trace for me so I'm not 100% sure I understand what the web test is doing. It's 4:00 AM here though, so it's entirely possible that sleep deprivation is causing me to be even more confused than normal :) -- Ryan 23-Sep-2008 04:05 PDT

OK, here is, what I do - the webtest does ;-). So far I do have two webtests.

  • The first one configures the newly clean jamwiki installation by entering a path to the homeDir, name of the admin, and the password (two times) and check the success by validating the title of the jamwiki start-page and a welcome-string.
  • The second one logs in as the configured admin and enters firstname, lastname and displayname and does a save. At this point I get an error displayed on the page (so it is related to the stacktrace above).
    Fehler
    Ein Systemfehler ist aufgetreten. Die Fehlermeldung lautet:
    Ein unbekannter Systemfehler ist aufgetreten. Die Fehlermeldung lautet: java.lang.IllegalArgumentException: Cannot encrypt a null or empty string.
    

    Probably there was a mandatory field - the test did not notice. ok I found the reason. The user has to enter old and new passwords. ;-) -- mbert 23-Sep-2008 10:59 PDT

Thanks - that clears it up and should be easy to fix. I should have spent more time investigating, but I'm not at my best before 6 AM... -- Ryan 23-Sep-2008 11:49 PDT
revision 2328 should resolve the blank password error. Thanks for catching that as I most likely would have missed it during my normal pre-release testing. I'll have to take a closer look at getting your web tests running on my local machine... -- Ryan 23-Sep-2008 19:21 PDT

Hi Ryan, the fix is not working! I added a webtest for changing the password for the admin-user it works, but adding/changing only the name without the password fails. So I will extend the documentation for the webtests, next time ;-). --mbert 27-Sep-2008 12:21 PDT

Thanks for continuing to test! The way the code is currently setup is that you must enter your old password in order to change any account fields - if you don't you get the message "Invalid old password". Is that what you're talking about, or is there a system error thrown somewhere? If it's just the "invalid password" error then the code is behaving as expected, although it's not particularly user-friendly. Note that having just checked Mediawiki's user account management, I'd be fully in favor of modifying JAMWiki to follow similar behavior, but that's probably a task better handled as a Tech: request or feature request for a future release. -- Ryan 27-Sep-2008 14:01 PDT

Hi Ryan, the error is not: "invalid password" it is:

Ein Systemfehler ist aufgetreten. Die Fehlermeldung lautet:
Ein unbekannter Systemfehler ist aufgetreten. Die Fehlermeldung lautet: java.lang.IllegalArgumentException: Cannot encrypt a null or empty string.

So there is no hint about the missing (old) password. -- mbert 28-Sep-2008 05:49 PDT

Is there a stacktrace available that shows where the source of the error is? I'm so far unable to reproduce, and as far as I can tell the following code in DatabaseUserHandler.authenticate() should prevent a null or empty password from being encrypted:

	// password is stored encrypted, so encrypt password
	if (StringUtils.isBlank(password)) {
		return false;
	}
	String encryptedPassword = Encryption.encrypt(password);

-- Ryan 28-Sep-2008 07:22 PDT

Bug in svn Revision: 2344

Hi Folks, hi Ryan, I just checked out the actual sources and started my webtests.

When I login on a new clean jamwiki-installation (thats what one of my webtests do) and try to change the admin password I get an error (after I clicked on the link: <clickLink label="${usermenu.account}"/>):

On the page I see:

Ein Systemfehler ist aufgetreten. Die Fehlermeldung lautet:
 
javax.el.PropertyNotFoundException: The class 'org.jamwiki.model.WikiUserInfo' does not have the property 'writeable'.

I the logs I see:

INFO: Loaded page /jamwiki-war/en/Special:Account (0.18 s.)
04.10.2008 11:53:43 org.jamwiki.utils.WikiLogger severe
SCHWERWIEGEND: Error in JSP page
javax.el.PropertyNotFoundException: The class 'org.jamwiki.model.WikiUserInfo' does not have the property 'writeable'.
       at javax.el.BeanELResolver.getBeanProperty(BeanELResolver.java:547)
       at javax.el.BeanELResolver.getValue(BeanELResolver.java:249)
       at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:143)
       at com.sun.el.parser.AstValue.getValue(AstValue.java:138)
       at com.sun.el.parser.AstOr.getValue(AstOr.java:54)
       at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:206)
       at org.apache.jasper.runtime.PageContextImpl.evaluateExpression(PageContextImpl.java:984)
       at org.apache.jsp.WEB_002dINF.jsp.register_jsp._jspx_meth_c_if_3(org.apache.jsp.WEB_002dINF.jsp.register_jsp:645)
       at org.apache.jsp.WEB_002dINF.jsp.register_jsp._jspService(org.apache.jsp.WEB_002dINF.jsp.register_jsp:142)
       at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:93)

trimmed long stack trace

so, I thought adding some new Webtest would be a good solution, but now I have no Idea what workaround I can use. -- mbert 04-Oct-2008 03:04 PDT

Thanks again for the report - for the next 1-2 weeks things will be less stable than normal using the latest Subversion code due to upgrades to make better use of Spring Security functionality - see Tech:Acegi Upgrade#Update October 2008. The bug you reported above is fairly easy to correct, and I think revision 2345 should resolve it. I'll try to keep the Subversion code mostly stable, but expect there to be some issues - bug reports are always appreciated, and I'll make an effort to incorporate your web test scripts into my local scripts (which I should have done ages ago - sorry!) -- Ryan 04-Oct-2008 09:42 PDT

Hi Ryan, don't blame yourself. Good if you try to include the webtests, so I get a response how the i18n inside the webtests is working. But the final aim should be calling the webtests with maven. At this moment I know a webtest-plugin but do not fully understand the configuration. The problem for me is how to start the jetty container bevor running the webtests and then shutdown jetty afterwards. So this may take some time - so long I will add more webtests. If you run on a onerous bug -> please make a suggestion on the webtest-page for a next test.

But for now my webtest is still not working with rev 2345! there is no "registerNewPassword" field visible for the admin. I was to doubtfull to change it by myself. -- mbert 04-Oct-2008 11:37 PDT
I've made some updates to the web tests to work around translation issues I was seeing, and they now mostly pass - the "JAMWiki installed successfully" message is still hard-coded in German, and I'm not quite sure how to work around that. If I've broken anything please feel free to revert my changes, but hopefully everything should work fine now no matter what language the user is using. These tests are pretty awesome, by the way - I'll have to learn more about them, but they could be exceptionally useful. -- Ryan 04-Oct-2008 12:48 PDT

Hi Ryan, the changes you did, work fine for me, except the small property loading in the build file. First the personal properties and then the default. Ant properties a immutable. -- mbert 11-Oct-2008 07:10 PDT

Hi Ryan, btw: I think there should be a note on the user-page that the old password is mandatory to change any value on this page, don't you think? -- mbert 11-Oct-2008 07:50 PDT
Thanks for fixing my changes to the web tests. A note about the password being required would help, although I'm also thinking about modifying that page to be more like Mediawiki's version, in which case the old password would only be required when changing passwords. Any suggestions or comments would be appreciated. -- Ryan 11-Oct-2008 10:23 PDT
Hi Michael - I'm working on a change now to allow updating of user data without entering the old password. The user would only need to enter his old password when changing password (in that case he must enter old password, new password and new password confirmation). I thought I would have this change done last night but there are some other issues to resolve (changing password seems to be broken right now) before this change can go in. -- Ryan 15-Oct-2008 07:32 PDT

Parsing of definition lists ';' and ':'

We are using jamwiki version 0.6.6 on oracle 11 database with tomcat 6.0.16 on solaris, but the behaviour is also visible on jamwiki.org. If we use a heading in a definition with ':' inside this is interpreted as a new definition list item:

;definition list title: some further title text
:definition list line

results in:

definition list title
some further title text
definition list line

I would except something like this:

definition list title: some further title text
definition list line

Am I wrong? --HB 06-Oct-2008 04:58 PDT

The current behavior should be consistent with Mediawiki - a bug requesting the current behavior was filed as Bug Reports/Resolved/0.6.x#Definition Lists and implemented for 0.6.6. To get the behavior you want you can add <nowiki> tags around the colon:
definition list title: some further title text
definition list line
-- Ryan 06-Oct-2008 08:00 PDT
hello Ryan, thanks for the answer. --HB 07-Oct-2008 01:38 PDT

RSS Feed function throws java.lang.NoClassDefFoundError

Using JamWiki 0.6.7 on WebSphere 6.0.2.31 with the built-in database. In general all is working fine but when going to Special:RecentChangesFeed page we get an http 500 caused by java.lang.NoClassDefFoundError.

See below for stack trace. Any suggestions much appreciated. [xx/xx/xx 12:05:54:361 GMT] 0000002f ServletWrappe E SRVE0014E: Uncaught service() exception root cause jamwiki: java.lang.NoClassDefFoundError

       at com.sun.syndication.io.SyndFeedOutput.<init>(SyndFeedOutput.java:44)
       at org.jamwiki.servlets.RecentChangesFeedServlet.handleRequestInternal(RecentChangesFeedServlet.java:147)
       at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
       at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
       at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
       at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
       at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
       at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
       at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1697)

The com.sun.syndication.io.SyndFeedOutput class is found in the rome-0.9.jar file that is distributed with JAMWiki. Can you confirm that the JAR file is present in your /WEB-INF/lib/ directory? -- Ryan 31-Oct-2008 10:48 PDT
The jar files are in place. I had a closer look at the stack trace and it seems to be an issue somewhere with the classloader inside the rome code. Maybe an issue with the java version, I will try to recompile rome 0.9 from source and let's see.

[11/3/08 10:09:30:162 GMT] 00000021 ServletWrappe E SRVE0014E: Uncaught service() exception root cause jamwiki: java.lang.VerifyError: (class: com/sun/syndication/io/impl/BaseWireFeedGenerator, method: generateForeignMarkup signature: (Lorg/jdom/Element;Ljava/util/List;)V) Incompatible argument to function at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:219) at com.sun.syndication.io.impl.PluginManager.getClasses(PluginManager.java:133) at com.sun.syndication.io.impl.PluginManager.loadPlugins(PluginManager.java:87) at com.sun.syndication.io.impl.PluginManager.<init>(PluginManager.java:55) at com.sun.syndication.io.impl.PluginManager.<init>(PluginManager.java:46) at com.sun.syndication.io.impl.FeedGenerators.<init>(FeedGenerators.java:47) at com.sun.syndication.io.WireFeedOutput.<clinit>(WireFeedOutput.java:44) at com.sun.syndication.io.SyndFeedOutput.<init>(SyndFeedOutput.java:44)

-- User:newirishman 03/11/2008 10:17 GMT

Thanks for the follow-up. Time permitting I'll take a closer look at this in the next few days. The rome.jar file hasn't been updated in a while, so maybe it's time to start looking for an alternative. One more question - are you using the default JDK for WebSphere, or have you done any customization? -- Ryan 03-Nov-2008 08:33 PST
Using the default JDK, which currently is 1.4.2_17. However, OS is SUN Solaris so its a SUN JDK (doesn't make it easier with IBM support). I recompiled but still get the error as the above; I will try the rome 1.0RC when I get the chance. -- User:newirishman 03-Nov-2008 17:41 GMT
Thanks again for the follow-up. As far as I'm aware you're the first report of this sort of issue, so I was hoping you might be using some exotic JDK... since that's not the case I did a quick Google search, and from this mailing list thread it sounds like it might be a classpath conflict of some sort, although I fail to see what would be causing it. I'll try to investigate a bit further in the next few days to see if I can find anything else that might be relevant. -- Ryan 04-Nov-2008 06:00 PST
I had a closer onto the classpath when the app is deployed in WebSphere. WebSphere comes with its own jdom.jar - an "older" version (JDOM version 1.0 Beta 7). I have replaced the jdom.jar that comes with WebSphere with the one bundled with jamwiki (JDOM version 1.0, built September 9 2004) and behold! it works now. Thanks for your help! -- User:newirishman 05-Nov-2008 14:34 GMT
Glad it got fixed, and thanks again for your persistence in debugging the issue! -- Ryan 05-Nov-2008 08:05 PST

sort_key of categories always empty

Using MSSQL as backend, each category has a NULL-value in column sort_key. With NULL as sort-key, pagination is broken and categories are listed in descendent order. Changing STATEMENT_SELECT_CATEGORIES works for me:

STATEMENT_SELECT_CATEGORIES = \
    BEGIN \
        DECLARE @COUNT int \
        DECLARE @TOP int \
        DECLARE @OFFSET int \
        DECLARE @LIMIT int \
        DECLARE @VWIKI_ID int \
        DECLARE @SQL varchar(500) \
        SET @VWIKI_ID = ? \
        SET @LIMIT = ? \
        SET @OFFSET = ? \
        SET @TOP = @LIMIT \
        SET @COUNT = (select count(distinct jam_category.category_name) from jam_topic join jam_category on jam_topic.topic_id = jam_category.child_topic_id where jam_topic.virtual_wiki_id = @VWIKI_ID) \
        IF (@OFFSET > @COUNT) SET @OFFSET = @COUNT \
        IF (@COUNT < @OFFSET + @LIMIT) SET @TOP = @COUNT - @OFFSET \
        SET @SQL = 'select * from ( ' \
                   + 'select top '+CONVERT(VARCHAR, @TOP)+' * from ( ' \
                      + 'select distinct top '+CONVERT(VARCHAR, @OFFSET + @LIMIT)+' jam_category.category_name, jam_category.sort_key ' \
                      + 'from jam_topic join jam_category on jam_topic.topic_id = jam_category.child_topic_id ' \
                      + 'where jam_topic.virtual_wiki_id = '+CONVERT(VARCHAR, @VWIKI_ID) \
                      + ' order by category_name ' \
                   + ') a ' \
                   + 'order by category_name desc ' \
                 + ') b ' \
                 + 'order by category_name' \
        EXEC(@SQL) \
    END

Important: changing the order from sort_key to category_name broke the statement, because the limit of @SQL (varchar(300)) is exceeded. --hp 30-Nov-2008 23:45 PST

Thanks, I'll put that change in place for the next release (I don't have MS SQL available, so feedback is very much appreciated). Let me know what name you would prefer to have used to credit you for this fix. -- Ryan 01-Dec-2008 08:26 PST
revision 2395 should resolve this issue. -- Ryan 01-Dec-2008 22:06 PST

Dead Link on Special:Search

The link to the documentation of lucene should be updated in ApplicationResources_de.properties (search.hints). [1] works for me! --hp 30-Nov-2008 23:53 PST

Thanks, they must have changed the URL after the most recent release. It should be an easy fix since the link is in the search.hints message key. Let me know how you would like to be credited in the CHANGELOG - I'll use your jamwiki.org login unless you prefer something different such as your full name. -- Ryan 01-Dec-2008 08:24 PST
revision 2396 should resolve this issue. -- Ryan 01-Dec-2008 22:06 PST

Uploads Fail for Some User Accounts

While trying to upload a file in version 0.6.7, one of my users was thrown an exception. Using another user account with the exact same privileges, I was able to upload the same file fine. The first traceback in the log is:

2008-12-31 13:47:28,314 SEVERE: org.jamwiki.servlets.ServletUtil - Servlet error
java.lang.Exception: Failure while executing insert into jam_file ( file_id, virtual_wiki_id, file_name, file_url, mime_type, topic_id, delete_date, file_read_only, file_admin_only, file_size ) values ( ?, ?,
 ?, ?, ?, ?, ?, ?, ?, ? )
        at org.jamwiki.db.WikiPreparedStatement.executeUpdate(WikiPreparedStatement.java:119)
        at org.jamwiki.db.AnsiQueryHandler.insertWikiFile(AnsiQueryHandler.java:755)
        at org.jamwiki.db.AnsiDataHandler.addWikiFile(AnsiDataHandler.java:147)
        at org.jamwiki.db.AnsiDataHandler.writeFile(AnsiDataHandler.java:1205)
        at org.jamwiki.servlets.UploadServlet.upload(UploadServlet.java:264)
        at org.jamwiki.servlets.UploadServlet.handleJAMWikiRequest(UploadServlet.java:63)
        at org.jamwiki.servlets.JAMWikiServlet.handleRequestInternal(JAMWikiServlet.java:74)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.jamwiki.authentication.JAMWikiExceptionMessageFilter.doFilter(JAMWikiExceptionMessageFilter.java:71)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:124)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:54)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:58)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:595)
Caused by: java.sql.SQLException: Attempt to insert null into a non-nullable column: column: MIME_TYPE table: JAM_FILE in statement [insert into jam_file ( file_id, virtual_wiki_id, file_name, file_url, mime_
type, topic_id, delete_date, file_read_only, file_admin_only, file_size ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )]
        at org.hsqldb.jdbc.Util.throwError(Unknown Source)
        at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
        at org.jamwiki.db.WikiPreparedStatement.executeUpdate(WikiPreparedStatement.java:111)
        ... 56 more

And a later exception also related to the upload:

2008-12-31 13:47:46,963 SEVERE: org.jamwiki.servlets.ServletUtil - Servlet error
java.lang.Exception: No topic exists for en / Image:cacert.pem
        at org.jamwiki.db.AnsiDataHandler.getAllWikiFileVersions(AnsiDataHandler.java:301)
        at org.jamwiki.servlets.ServletUtil.viewTopic(ServletUtil.java:899)
        at org.jamwiki.servlets.ServletUtil.viewTopic(ServletUtil.java:839)
        at org.jamwiki.servlets.TopicServlet.view(TopicServlet.java:59)
        at org.jamwiki.servlets.TopicServlet.handleJAMWikiRequest(TopicServlet.java:45)
        at org.jamwiki.servlets.JAMWikiServlet.handleRequestInternal(JAMWikiServlet.java:74)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.jamwiki.authentication.JAMWikiExceptionMessageFilter.doFilter(JAMWikiExceptionMessageFilter.java:71)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:124)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter.doFilter(JAMWikiAnonymousProcessingFilter.java:54)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:58)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:595)

The file being uploaded was an SSL CA certificate. A text file with a ".pem" extension. It seems not to know the content type of the file and is failing because of it? Isn't there a fail-over case to just send things "application/octet-stream" or something similar? Any ideas why it uploads fine for me but not the other user?

Thanks for your hard work. JAMWiki has been a great addition to our infrastructure thus far. --Tim 31-Dec-2008 12:44 PST

Thanks for the report - I'll take a look at this next chance I get. The upload code is actually using the Apache Commons upload package, which I assumed defaulted the MIME type, but if that's not the case then it will be a simple matter to fix. -- Ryan 31-Dec-2008 19:01 PST
revision 2403 will use a default MIME type of "application/unknown" whenever the MIME type cannot be determined. That should resolve this issue. I've credited you as "Tim" in the CHANGELOG - let me know if you would prefer something different. -- Ryan 01-Jan-2009 10:16 PST

Link is not working

This link will not be renderd correctly: [2] -- mbert 18-Jan-2009 07:41 PST

Thanks - I'm working on parser updates today so I should be able to get that fixed for 0.7.0. -- Ryan • (comments) • 18-Jan-2009 09:52 PST
revision 2435 should resolve this issue. -- Ryan • (comments) • 18-Jan-2009 15:52 PST

IllegalStateException from Spring Security on Resin

When attempting to access a page that generates an AccessDeniedException using the Resin server an IllegalStateException is thrown due to an attempt to redirect after the response has been committed. Thus far I haven't been able to track down where the problem is, and the same code works with Tomcat, but this issue may hold up the final 0.7.0 release until it is solved. -- Ryan • (comments) • 17-Feb-2009 21:27 PST

revision 2477 fixes the IllegalStateException, but there is still a problem with Resin losing the access denied error message. I believe the problem is due to the fact that Spring Security namespace configuration does not allow use of a custom AccessDeniedHandler, so JAMWikiExceptionTranslationFilter is attempting to provide this functionality. As a result there are two RequestDispatchers that fire, and when the first one is processed it clears all error key info. -- Ryan • (comments) • 22-Feb-2009 16:31 PST
I think revision 2478 will resolve the remaining issues. This commit will need some additional testing, but this was the last major remaining hurdle holding up the 0.7.0 release. -- Ryan • (comments) • 22-Feb-2009 19:06 PST

Four dash parsing broken

Parsing of four dashes is broken for 0.7.0 when surrounded by newlines:


the above is broken.

this works


-- Ryan • (comments) • 20-Feb-2009 00:16 PST

revision 2476 fixes this issue. -- Ryan • (comments) • 20-Feb-2009 20:49 PST

Unable to upload file - missing class

When trying to upload a file I get a noClassDefFoundError. I recently upgraded to tomcat5.5 and am not sure if this is related at all. Unfortunately I had n't tried upload file since upgrading jamwiki to 0.6.0 so am unable to pin point where this problem started.

2007-10-21 09:23:35,529 SEVERE: org.jamwiki.servlets.ServletUtil - Servlet error
java.lang.NoClassDefFoundError
	at javax.imageio.ImageReader.getSourceRegion(ImageReader.java:2544)
	at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1315)
	at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1579)
	at javax.imageio.ImageIO.read(ImageIO.java:1400)
	at javax.imageio.ImageIO.read(ImageIO.java:1322)
	at org.jamwiki.utils.ImageUtil.loadImage(ImageUtil.java:128)
	at org.jamwiki.utils.ImageUtil.isImage(ImageUtil.java:111)
	at org.jamwiki.servlets.UploadServlet.upload(UploadServlet.java:195)
        truncated.......

--CB 21-Oct-2007 08:26 PDT

I just tried uploading a PNG on my local box (Windows, Sun JDK 1.4.2, Tomcat 5.0) and on jamwiki.org (Debian, Sun JDK 1.5.0, Tomcat 5.5) and both seemed to work OK. The stacktrace you provided looks like it is coming from the JDK - what JDK are you using? Is it possible the Tomcat upgrade is pointing to a different JDK version than your previous Tomcat install? Based solely on the stack trace I suspect some sort of configuration issue rather than a JAMWiki code issue, but I'm usually wrong about a thousand times a day, and this may be one of those cases :) -- Ryan 21-Oct-2007 09:45 PDT

Thanks, good to know it is working for someone. I am using Sun JDK 1.5 and Tomcat 5.5, same JDK I was using before the tomcat/ubuntu upgrade. --70.123.157.217 21-Oct-2007 13:02 PDT

This same issue is occurring on jamwiki.org after upgrading to the latest Debian release so I'll investigate and try to find a solution. -- Ryan • (comments) • 21-Feb-2009 09:24 PST

The problem appears to be a system configuration issue in Debian - after tweaking the CLASSPATH I got the following message in the log which eventually led to a solution:

java.lang.UnsatisfiedLinkError: /usr/lib/jvm/java-1.5.0-sun-1.5.0.17/jre/lib/i386/libawt.so: libmlib_image.so:
cannot open shared object file: No such file or directory

I won't pretend to fully understand the issue, but the solution (for jamwiki.org at least) is available from https://bugs.launchpad.net/debian/+source/sun-java5/+bug/162232:

"I have the same issue, solved with the following command:
sudo ln -s /usr/lib/jvm/java-1.5.0-sun/jre/lib/i386/libmlib_image.so /usr/lib
sudo ldconfig

Under AMD64 system this can be solved by creating the /etc/ld.so.conf.d/java.conf with the following contents:
/usr/lib/jvm/java-1.5.0-sun/jre/lib/i386

Under x86 this doesn't work so the "ln -s" trick is needed."

-- Ryan • (comments) • 21-Feb-2009 18:12 PST

Potential session hijack

If you go to the site for the first time (or after enough time that your previous session has expired), you are given a new session. For example, go to: http://www.jamwiki.org (include the www subdomain), you get forwarded to the homepage and it includes the session ID in the query string, like this: http://jamwiki.org/wiki/en/StartingPoints;jsessionid=67431F28377CD519F0A668A582AA4745

If someone were to sniff it off your traffic, they could potentially hijack your session. -- scroco 25-Aug-2006 11:12 PDT

I'll take a look, although do you know of a way that other sites handle this? I think the session ID is always stored in either a cookie or in the URL, so don't most application servers check both the session ID and the origin address to verify that a session is valid? In addition, login credentials are stored in an (encrypted) cookie, so I'm not sure how much damage could be done by stealing the session ID. That said, I'm not very knowledgeable in this area, so any advice is appreciated. -- Ryan 25-Aug-2006 12:20 PDT
jsessionid is a mechanism for making sessions work even if the client doesn't support cookies. It has some problems, though. In my web applications, I use the filter described in http://randomcoder.com/articles/jsessionid-considered-harmful . It works well. The downside, of course, is that stuff breaks for clients who don't support cookies. But a huge number of sites on the web are breaking for those clients.
When hosting jamwiki in Jetty standalone, the inclusion of the jsessionid in the URL results in an error condition on the initial page view: StartingPoints;jsessionid=67431F28377CD519F0A668A582AA4745. The topic "StartingPoints;jsessionid=67431F28377CD519F0A668A582AA4745" does not currently exist. To create it please follow the link: StartingPoints;jsessionid=67431F28377CD519F0A668A582AA4745. This results in a very confusing user experience when first viewing a wiki or returning after a session expiration. Apparently, not all web servers automatically deal with the jsessionid. spiralmike 28-Nov-2008 19:47 PDT
Thanks for the report - it should be the web application server that added the jsessionid value, so I suspect that the JAMWiki code that is suppposed to determine the current topic is at fault, although this most likely means that Jetty's servlet implementation differs from other app servers. I'll investigate. -- Ryan 29-Nov-2008 07:50 PST
I solved this by disabling session ID URL rewriting. Jetty standalone release is based on Jetty 7. After much ineffective configuration tweaks, I ended up making a jamwiki.xml for jetty standalone to initialize the context properly. (Note- I'm not a Jetty expert). See example:
 <Configure class="org.mortbay.jetty.webapp.WebAppContext">
   <Set name="resourceBase">/opt/jamwiki
   </Set>
   <Set name="connectorNames">
     <Array type="String">
       <Item>default</Item>
     </Array>
   </Set>
 
   <Set name="initParams">
     <Map>
       <Entry>
         <Item>org.mortbay.jetty.servlet.SessionIdPathParameterName</Item>
         <Item>none</Item>
       </Entry>
         
     </Map>
   </Set>
 
 </Configure>  
This is related to the use of "path parameters"- a semicolon followed by name-value pairs in any URI path component (eg. /x/y/z;name=value?q1=a&..., or /x/y;name=value/z;v=2.1?q1a...). The jsessionid is injected as a path parameter, but IMHO should be filtered by the web server and not returned in getRequestURI() and similar methods. I suppose that my version of Jetty standalone, which uses Jetty 7 pre-release, is broken, because it fails to strip jsessionid from getRequestURI(), thus confusing web applications that do not expect their URI paths to be parameterized. spiralmike 22-Dec-2008 20:42 PDT.
Thanks for taking the time to resolve the issue and let me know about the solution. There are similar bug reports for an older version of Tomcat in which semicolon-params were not being removed when getRequestURI() was called, so this sounds like a somewhat common error. I'm hoping to have some time over the holidays to do some programming, so with luck I'll be able to put in a workaround so that this doesn't hit anyone else. -- Ryan 23-Dec-2008 07:26 PST
revision 2402 should resolve this issue. According to this discussion it isn't completely clear whether or not getRequestURI should strip out path parameters or not, so JAMWiki will now do that if the servlet container does not. -- Ryan 29-Dec-2008 20:57 PST

LDAP in version 0.7

There is a entry ldap-authentication-provider missing for LDAP authentication. I'd searched 3 days for the cause. In version 0.7 Spring can only see the user details like the roles and fails when mapping to a user. With the ldap-authentication-provider this works like expected.


        <ldap-server id="ldapServer" url="ldap://192.168.1.100/dc=mycompany,dc=com" port="389" manager-dn="cn=admin,dc=mycompany,dc=de" manager-password="mypasswd"/>
        <ldap-authentication-provider server-ref="ldapServer" group-search-filter="member={0}" group-search-base="ou=groups" user-dn-pattern="uid={0},ou=people" />
        <authentication-provider>
                <ldap-user-service server-ref="ldapServer" group-search-filter="member={0}" group-search-base="ou=groups" user-search-filter="uid={0}" user-search-base="ou=people" />
        </authentication-provider>


Thanks! I'll update the LDAP sample for JAMWiki 0.7.1. Please let me know if you would like a credit in the CHANGELOG, and if so what name to use. -- Ryan • (comments) • 09-Mar-2009 11:23 PDT
This would be nice. Name: Tobias Kalbitz of course searching for users should also work with
<ldap-authentication-provider server-ref="ldapServer" group-search-filter="member={0}" group-search-base="ou=groups" user-search-filter="uid={0}" user-search-base="ou=people" /> 
Thanks again - this change has been committed as revision 2508. I don't personally use LDAP (I did testing for 0.7.0 with an Apache users.ldif sample file) so it's definitely good to have some confirmation that the Spring integration is working as advertised. -- Ryan • (comments) • 09-Mar-2009 17:28 PDT

Role Administration Problem

I upgraded from 0.6.7 to 0.7.0 without issue. I have a few roles set up to restrict access to a few pages and I had removed all access to GRUOP_ANONYMOUS by unchecking all of the roles. When I opened the Roles tab in the Admin page the GROUP_ANONYMOUS group was not displayed, only the GROUP_REGISTERED_USERS was showing. I also noticed if I created a new user and then typed that user's name in the Assign User Roles/Search for Users by Login nothing was displayed.

I went back to my 0.6.7 install and added the roles back into the GROUP_ANONYMOUS group and then converted to 0.7.0 again and this time I can see both groups under Admin Roles.

Basically it looks like users and groups are not being displayed unless they have some roles checked. So if you add a new user it is not possible to give that user additional new roles. --Tom Schueller 15-Mar-2009 17:01 PDT

This sounds like the same issue that was reported at Feedback#Search for users ... broken in v0.7.0. It will definitely be fixed for the upcoming 0.7.1 release. Thanks for the report. -- Ryan • (comments) • 21-Mar-2009 18:22 PDT

Default Topic property ignored

--Bob White 13-Mar-2009 19:13 PDT I just installed version 0.7.0 (Mar 13 09) and find that no matter what I set the Default Topic to, it remains StartingPoints.

Would it be possible to provide the exact steps you used? I just tried the following on my local instance and it worked as expected:
  1. Go to Special:Maintenance
  2. For the "en" virtual wiki change "StartingPoints" to "Sandbox" and click update.
  3. Clicking on the logo in the top left or typing in http://localhost/wiki/ or http://localhost/wiki/en/ in my browser both take me to http://localhost/wiki/en/Sandbox.
In addition, if there is additional info that might help (app server, etc) I can try to reproduce. Note, however, that I'm leaving on a boat late tomorrow afternoon (EDT) and won't return for a week, so I may not immediately be able to address the problem. Thanks for the bug report! -- Ryan • (comments) • 13-Mar-2009 19:25 PDT
--12.25.58.57 13-Mar-2009 20:11 PDT I see now. Thanks. Not a bug at all.

Search for users ... broken in v0.7.0

In JAMWiki 0.7.0 on the Special:Roles page the search for users doesn't yield any results (except when searching for the logged in admin). --tapaya 05-Mar-2009 08:33 PST

This is the second report of this issue. I wasn't able to reproduce it earlier in my local environments, but if I can find a way to do so then I'll try to get a 0.7.1 fix release out. Note that I'll be leaving for two weeks of vacation starting tomorrow night, so if I can't get a fix out in the next two days it might take a couple of weeks to resolve. If there is any additional information you can provide (log messages, steps to reproduce, application server, database) it would be appreciated. -- Ryan • (comments) • 05-Mar-2009 10:10 PST
...\Tomcat 6.0\temp\jamwiki.log.0 doesn't say anything about this issue; are there other files to consider? Reproducing is easy: just log in as admin, go to the Special:Roles page and search for any but the admin user ... no results. My setup is Windows XP/Tomcat 6.0/JAMWiki 0.7.0/H2 1.1.108. Can you think of a workaround to assign admin rights to users? --tapaya 06-Mar-2009 01:28 PST
I suspect it might be something specific to the database, so the SQL files in the WEB-INF/resources directory will be something to look at. I still need to pack for my trip, so if I don't get to this before the plane leaves tonight I'll have time while sitting in the airport tomorrow. -- Ryan • (comments) • 06-Mar-2009 12:50 PST
I haven't done a lot of testing yet, but I believe that updating /WEB-INF/resources/sql.ansi.properties to change the following property will resolve the problem:

STATEMENT_SELECT_AUTHORITIES_LOGIN = \
    select jam_wiki_user.wiki_user_id, jam_users.username, \
    jam_authorities.authority \
    from jam_wiki_user, jam_users \
    left outer join jam_authorities on ( \
      jam_users.username = jam_authorities.username \
    ) \
    where jam_users.username = jam_wiki_user.login \
    and lower(jam_users.username) like ? \
    order by jam_users.username 

This may actually have been broken on other databases, but I had enough data in my system that I never noticed. Thanks for the report and the followup. The fix is committed as revision 2499. -- Ryan • (comments) • 06-Mar-2009 18:07 PST

special-chars in article names

Creating a new article with special-chars works only if you first create a link to it (try TestÜmlaut). Attaching this name to the URL breaks them (try [3]) and - for me worse then the first constraint - Special:Move also breaks such characters (ö,ä,ü,...). Special-chars in the description-field of Special:Move are also broken. --hp 21-Jan-2009 23:54 PST

Did anyone took a closer look to my problem? I think the entry "Problem with german umlaut in article and category title" could be quite the same and these two could be solved together. UTF-8 works like a charm in articles and titles, following doesn't:
  • Special:Move breaks special chars
  • description-field of Special:Move and Special:Manage
  • [4] works not

--hp 08-Apr-2009 02:15 PDT

I'll take a closer look, but this seems to work for me using Firefox. Since it looks like you're able to reproduce the problem on jamwiki.org, what browser are you using? And is it set to use UTF-8 encoding ("View → Character Encoding" in Firefox). Thanks! -- Ryan • (comments) • 08-Apr-2009 07:03 PDT
Thank you, Ryan! I'm also using Firefox (3.0.8) and its encoding is automatically set to UTF-8 on jamwiki.org. In ApplicationResources_de.properties, "topic.notcreated" gets the value "Der Artikel {0} existiert zur Zeit noch nicht. Um ihn anzulegen folgen Sie bitte diesem Link\: {1}.". The second param will be the <jamwiki:link /> with the topic name as its value. I think here happens the replacement of an german umlaut with its html-replacement (ü -> &uuml;). So the article name will contain these html-replacements. --hp 08-Apr-2009 22:12 PDT
Thanks for the additional info - I'm able to reproduce the problem and will see if I can figure out the cause for JAMWiki 0.7.2. -- Ryan • (comments) • 09-Apr-2009 20:50 PDT
I think revision 2573 will resolve this issue. I'd like to do a bit more testing, but the URL provided above now works on my local setup. -- Ryan • (comments) • 12-Apr-2009 11:01 PDT
Thanks you! On jamwiki.org, the URL-issue seems to be solved, but moving an article with special chars in name breaks them... I created a Site Sandbox/ÖÄÜ with appending the name to the URL, but moving this site to Sandbox/ÖÄÜ-test did replace the UTF-8 chars. --hp 14-Apr-2009 00:47 PDT
Thanks for following up - I was doing four things at once when I looked at this Sunday and obviously failed to address the full bug report. I'll look into the move and other issues next chance I get - I suspect it's a similar problem to the one already addressed. -- Ryan • (comments) • 14-Apr-2009 08:11 PDT
I think revision 2580 resolves the remaining two issues. I'll do a bit more testing to verify. -- Ryan • (comments) • 19-Apr-2009 15:44 PDT

MS-SQL-Error in 0.7.1

Using MS-SQL as backend, an exception is thrown while looking for user changes. In STATEMENT_SELECT_WIKI_USER_CHANGES_LOGIN (sql.mssql.properties) @SQL is declared as varchar(900) and should be at least varchar(1000), otherwise the statement is broken. --hp 08-Apr-2009 00:21 PDT

Thanks for the fix, I'll get this into the next release. -- Ryan • (comments) • 08-Apr-2009 07:00 PDT
revision 2563 should resolve this issue. Thanks! -- Ryan • (comments) • 08-Apr-2009 17:44 PDT

No Toolbar available in Preview

In Jamwiki 0.7.1 my Toolbar gets lost at preview, because EditServlet sets the attribute "editor" not when isPreview(request) returns true.

<c:when test="${editor == 'toolbar'}">
  <%@ include file="editor-toolbar-include.jsp" %>
</c:when>
 if (isPreview(request)) {
   preview(request, next, pageInfo);
   return;
 }
 /* ... */
 next.addObject("editor", editor);

--hp 08-Apr-2009 02:01 PDT

Thanks, looks like this was introduced in JAMWiki 0.7.0. I'll try to get a fix together shortly. -- Ryan • (comments) • 08-Apr-2009 06:59 PDT
This was already fixed on trunk with revision 2489. I'll make sure the fix gets backported into JAMWiki 0.7.2. -- Ryan • (comments) • 08-Apr-2009 17:47 PDT
revision 2566 fixes this problem for 0.7.2. -- Ryan • (comments) • 19-Apr-2009 15:28 PDT

0.7.0/0.7.1 failure with Resin 3.2.1

It fails to access any page. I ended up installing with Tomcat 5.5 (which worked nicely) and then I moved it back to Resin... but same problem. Maybe this is a Resin problem. Not sure. I need to stick with Resin because Resin/Quercus runs (properly) with phpMyAdmin whereas phpMyAdmin fails with Tomcat/Quercus. Is there a tweak I can make?

-- James (james dot moger at gmail dot com)

[16:40:12.921] {http--8080-0}   at java.lang.Thread.run(Thread.java:619)
javax.el.PropertyNotFoundException: array index '1' is invalid
        at javax.el.ArrayELResolver.getValue(ArrayELResolver.java:118)
        at com.caucho.jsp.el.PageContextELResolver.getValue(PageContextELResolver.java:172)
        at com.caucho.el.ArrayResolverExpr.getValue(ArrayResolverExpr.java:148)
        at com.caucho.el.Expr.evalObject(Expr.java:224)
        at _jsp._web_22dinf._jsp._setup__jsp._jspService(_setup__jsp.java:79)
        at _jsp._web_22dinf._jsp._setup__jsp._jspService(_setup__jsp.java:30)
        at com.caucho.jsp.JavaPage.service(JavaPage.java:61)
        at com.caucho.jsp.Page.pageservice(Page.java:580)
        at com.caucho.server.dispatch.PageFilterChain.doFilter(PageFilterChain.java:195)
        at com.caucho.server.webapp.DispatchFilterChain.doFilter(DispatchFilterChain.java:97)
        at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:266)
        at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:293)
        at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:111)
        at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:236)
        at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:257)
        at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1183)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:902)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:114)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:91)
        at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:103)
        at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:169)
        at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
        at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
        at org.jamwiki.servlets.JAMWikiFilter.doFilter(JAMWikiFilter.java:59)
        at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
        at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:189)
        at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:266)
        at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:292)
        at com.caucho.server.port.TcpConnection.handleRequests(TcpConnection.jav
a:577)
        at com.caucho.server.port.TcpConnection$AcceptTask.doAccept(TcpConnection.java:1211)
        at com.caucho.server.port.TcpConnection$AcceptTask.run(TcpConnection.java:1152)
        at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:759)
        at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:681)
        at java.lang.Thread.run(Thread.java:619)
I tested Resin 3.1.8 on my Windows laptop prior to releasing 0.7.0 and didn't run into this problem, so I'll have to try 3.2.1. Was this on an existing install that was upgraded, or a new install? Also, what OS and JDK are you using? Thanks! -- Ryan • (comments) • 08-Apr-2009 15:10 PDT
New/Clean install; just starting out with JAMWiki. Resin 3.2.1, MySQL 5.0.51, WinXP, JDK 1.6.0_12. I also tried 0.6.7 and ran into a different problem - something about fmt:bundle not bound. Of course this also worked just fine on Tomcat 5.5. -- James • 08-Apr-2009 18:41 PDT
Thanks - the fmt:bundle thing got fixed for 0.7.0 (revision 2475), but apparently there's another issue. Resin always seems to be a problem child and I don't test with it enough... they are religious about following standards though, so it's generally a safe bet that if Resin works, so does everything else. I'll make sure to look into this in the next couple of days - thanks for the bug report, and sorry for the trouble. -- Ryan • (comments) • 08-Apr-2009 19:40 PDT
The problem is apparently due to Resin not accepting empty/null array values - there are four instances of [1] on setup.jsp, any one of which may occasionally be empty (the same is true on many other pages). I'll have to dig into the specs to see if this is a Resin bug or if it's simply fortuitous that it worked on other app servers and then see if an easy solution is available. -- Ryan • (comments) • 11-Apr-2009 11:44 PDT
I patched 0.6.7 for the fmt: / f: binding issue and it does work on Resin after that, BUT I have seen the 0.6.7 version fail on Resin 3.2.1 with this same exception. I may give Resin 3.1.8 a try to see if that works better; technically 3.2.1 is a development version released last Oct/Nov.... but the real development is on 3.9.x which will be Resin 4.0. So I'm unsure where 3.2.1 is heading at the moment. Thanks for your interest in fixing this. -- James • 11-Apr-12:51 PDT
I believe that revision 2564 will resolve this problem. I've tried viewing every page with Resin 3.2.1 and it seems to work, although any further bug reports would be appreciated. -- Ryan • (comments) • 11-Apr-2009 18:07 PDT

TOC Rendering Error

When the TOC depth exceeds the MAX_TOC_DEPTH JAMWiki property the rendering breaks, adding additional list elements. Example:


<!-- assume MAX_TOC_DEPTH is 3 -->
== Good ==
=== Good ===
==== Still Good ====
===== Broken! =====

-- Ryan • (comments) • 10-Apr-2009 14:00 PDT

revision 2572 should resolve this problem. -- Ryan • (comments) • 12-Apr-2009 10:39 PDT

Print Category related article text above category listing

The Mediawiki style of printing the categories related texts before the category listing seems to be better readable. See Category:Developer Documentation, where the text

Articles related to Developer Documentation

is printed below the category listing -- Axel Kramer 17-Apr-2009 08:16 PDT

That should be an easy change, thanks for pointing it out. -- Ryan • (comments) • 17-Apr-2009 08:24 PDT
revision 2579 should resolve this issue. The fix is queued for JAMWiki 0.7.2. -- Ryan • (comments) • 19-Apr-2009 15:14 PDT

Group with no roles assigned does not display

I had reported this in version 0.7.0 and there was a related problem where a user with no roles checked would not display. I can now search for a user who has no roles set and the user will display correctly. But I'm still having the issue with the GROUP_ANONYMOUS group. In 0.6.7 I had removed the ROLE_VIEW so that there is not access unless you already have an account. When I upgraded the group GROUP_ANONYMOUS does not show up under the Admin/Roles page.

As a work around I went back to 0.6.7 and added a new role, that basically does nothing, but since I have it checked in the GROUP_ANONYMOUS it still allows me to see the group in the admin page. --Tom Schueller 05-May-2009 16:25 PDT

I'll investigate this one soon - hopefully the fix is similar to the user role change and can be done simply by updating the SQL properties file. Thanks for the report. -- Ryan • (comments) • 05-May-2009 22:21 PDT
revision 2588 should resolve this issue. The change is simply to modify a query in /resources/sql.ansi.properties, so if you need this fixed and don't want to wait for JAMWiki 0.7.2 you can simply modify that file in your local installation and then restart your app server. -- Ryan • (comments) • 10-May-2009 18:41 PDT

Upgrade to 0.7.0 (or .1, or .2) MS-SQL

Automatic Upgrade from Version 0.6.7 to 0.7.0 or higher fails when using MSSQL as backend. Manual Upgrade works, but statements must be changed (see mssql jamwiki upgrade 0.7.0.sql - running these statements worked for me). --hp 19-May-2009 01:23 PDT

Thanks for the files... if you or anyone has suggestions for how to test multiple databases easily I'd be grateful as these sort of compatibility issues seem to creep up every time there are major database schema changes. I've got access to Postgres, HSQL, MySQL and Oracle for testing, but the others tend to get overlooked during development unless someone else tests... -- Ryan • (comments) • 19-May-2009 10:18 PDT
revision 2592 should resolve this issue - I wasn't able to test since I don't have MS SQL, but hopefully I got everything. Thanks again for the fix! -- Ryan • (comments) • 25-May-2009 21:14 PDT

Upgrade to 0.7.2 Beta1 on SuSE Linux

While upgrading on windows worked (after solving MSSQL-problems), I cannot edit the Stylesheet on SuSE Linux ... when I try to save, I get the following message:

Ein unbekannter Systemfehler ist aufgetreten. Die Fehlermeldung lautet: net.sf.ehcache.CacheException: org.jamwiki.WikiBase.CACHE_PARSED_TOPIC_CONTENTCache: Could not remove disk store entry for en/StyleSheet. Error was org.jamwiki.WikiBase.CACHE_PARSED_TOPIC_CONTENT Cache: The Disk store is not active..

When I run into this problem, a restart of tomcat is necessary, because every other action ends in a stack overflow...

java.lang.StackOverflowError
	at java.nio.charset.Charset.atBugLevel(Unknown Source) 
	at java.nio.charset.CharsetDecoder.<init>(Unknown Source)
	at java.nio.charset.CharsetDecoder.<init>(Unknown Source)
	at sun.nio.cs.UTF_8$Decoder.<init>(Unknown Source)
	at sun.nio.cs.UTF_8$Decoder.<init>(Unknown Source)
	at sun.nio.cs.UTF_8.newDecoder(Unknown Source)
	at java.nio.charset.CharsetEncoder.isLegalReplacement(Unknown Source)
	at java.nio.charset.CharsetEncoder.replaceWith(Unknown Source)
	at java.nio.charset.CharsetEncoder.<init>(Unknown Source)
	at java.nio.charset.CharsetEncoder.<init>(Unknown Source)
	at sun.nio.cs.UTF_8$Encoder.<init>(Unknown Source)
	at sun.nio.cs.UTF_8$Encoder.<init>(Unknown Source)
	at sun.nio.cs.UTF_8.newEncoder(Unknown Source)
	at java.lang.StringCoding$StringEncoder.<init>(Unknown Source)
	at java.lang.StringCoding$StringEncoder.<init>(Unknown Source)
	at java.lang.StringCoding.encode(Unknown Source)
	at java.lang.String.getBytes(Unknown Source)
	at java.net.URLEncoder.encode(Unknown Source)
	at org.jamwiki.utils.Utilities.encodeAndEscapeTopicName(Utilities.java:171)
	at org.jamwiki.utils.LinkUtil.appendQueryParam(LinkUtil.java:73)
	at org.jamwiki.utils.LinkUtil.buildEditLinkUrl(LinkUtil.java:97)
	at org.jamwiki.utils.LinkUtil.buildTopicUrl(LinkUtil.java:346)
	at org.jamwiki.utils.LinkUtil.buildEditLinkUrl(LinkUtil.java:105)
	at org.jamwiki.utils.LinkUtil.buildTopicUrl(LinkUtil.java:346) 

I hope I can dig into that one soon, any suggestions? --hp 19-May-2009 02:49 PDT

This is the first I've seen of this error... my first guess would be that permissions to read/write the files in the File-system directory might have gotten changed, but an upgrade wouldn't do that so it's entirely possible that something else is going on. Do you by any chance have multiple instances of ehcache in your classpath? -- Ryan • (comments) • 19-May-2009 10:16 PDT
Thank you Ryan, this one could be removed. I did only an database-upgrade, the application was a fresh install (with working jamwiki.properties from other server)... of course homeDir didn't exists... I think that was the problem, it seems to work now! --hp 19-May-2009 22:47 PDT

Nested Templates

Moved from the Feedback page:

I'm trying to create a master template consisting of various sub-templates, each of those expecting some parameters.

One of my sub-templates (Country Profile Overview Country) is defined like:


{{{CountryOverview|Something about {{{Country|<Country Name>}}}...}}}

<noinclude>
<p><br /><br /><br />
----
'''Usage'''
----
This template is used to provide a standardize way of giving an overview over a particular country.
<pre><nowiki>
{{Country Profile Overview Country
|Country=<Country Name>
|CountryOverview=<Country Overview>
}}
<//nowiki><//pre>
----
[[Category:Template]]
[[Category:Sub-Template]]
</noinclude>

My master templates (Country Profile) incorporates the sub-template like:


__TOC__

== Overview {{{Country|<Country Name>}}} ==
{{Country Profile Overview Country
|Country={{{Country|<Country Name>}}}
|CountryOverview={{{CountryOverview|<Country Overview>}}}
}}

This master template I'm then using like:


{{Country Profile
|Country=San Marino
|CountryOverview={{{Country|<Country Name>}}} is a landlocked enclave in Italy...
}}

[[Category:Test]]
[[Category:Sandbox]]

As you can see, I'm passing a parameter ({{{Country|<Country Name>}}}) inside another parameter (CountryOverview). This results in:


Test Country Profile
------------------------------------------------------------------

Overview San Marino

{{{Country|<Country Name>}}} is a landlocked enclave in Italy...

How would I manage having the Country-parameter being replace appropriately? --Sil68 07-Apr-2008 07:24 PDT

Looks like you're doing everything right, but there's a bug in the template parsing. I've run into a few other issues, but unfortunately they're going to be rather tough to fix. I'll try to give this some attention this week, but please leave a gentle reminder if I haven't provided an update within the next five or six days. -- Ryan 07-Apr-2008 19:35 PDT
Hi Ryan, How is it going? :) --Sil68 13-Apr-2008 22:19 PDT
Thanks for the reminder :) I ended up spending the weekend working on fixing regressions related to parser changes and cleaning up the paragraph parsing, but templates are next on the to-do list. Sorry for the delay! -- Ryan 14-Apr-2008 08:09 PDT
Quick update - I've been busy with work and parser updates, but at the moment my plan is still to include a fix for your issue in the next release unless it turns out to be something that is very difficult to fix or that could cause a lot of regressions. Hopefully this week or next weekend I'll find some time to investigate. Sorry for the delay! -- Ryan 21-Apr-2008 08:38 PDT
Apologies for all of the delays - between all of the parser changes that have been going in lately and some very long hours at my workplace it's been three weeks and I still haven't gotten to any template changes. I've got your example template running on my local instance and I've started going through the code to see how best to get this issue fixed, but it's not a simple change. At this point I'm thinking it might make more sense to get the final 0.6.6 release done, and then look into template fixes for the next release. My plan is to freeze things and start testing by the end of this week (02 May), so if the template work doesn't happen by then it will probably slip to the next release. Sorry for the delay! Hopefully this won't inconvenience you too much. -- Ryan 27-Apr-2008 22:02 PDT
Nested template support was added for 0.7.0. -- Ryan • (comments) • 30-Aug-2009 18:55 PDT

Nested Lists Rendering Bug

Example:


* Outer list first item
** Inner list first item
this is a second line for the inner list first item
** Inner list second item (here is the bug with two bullets)
* Outer list second item

leads to:

  • Outer list first item
    • Inner list first item

this is a second line for the inner list first item

    • Inner list second item (here is the bug with two bullets)
  • Outer list second item

I forgot, this bug report is from: frafu 14-Apr-2009 07:41 PDT

I tried previewing this same syntax on Wikipedia and get the same (two bullet) result. Even though the current behavior is sort of crappy I'm a bit hesitant to introduce a change that breaks compatibility with Mediawiki unless there's a good reason to do so, and I suspect that in the above case most people familiar with Mediawiki would expect the "this is a second line for the inner list first item" line to NOT be part of a list. I'm open to being convinced otherwise, but in general since JAMWiki aims to be as compatible as possible with Mediawiki the argument "that's how Mediawiki does it" is the one I usually prefer. -- Ryan • (comments) • 14-Apr-2009 08:09 PDT
You're right. Mediawiki does the same. Ok, lets also copy the bugs. :-) frafu 14-Apr-2009 10:06 PDT
Ha! It's less about "copying the bugs" than letting them make the design decisions - in this case I'm honestly not sure what the "best" behavior would be. I'm sure this issue has probably been discussed at length on some Mediawiki forum somewhere with everyone arguing what behavior is correct, and I'm quite happy to let them deal with all of the arguments, make a decision, and we can then follow their lead. -- Ryan • (comments) • 14-Apr-2009 10:38 PDT

Upgrade from 0.5.1 to 0.7.1 with database migration

I'm trying to upgrade and migrate from 0.5.1. with HSQLDB (file database) to 0.7.1 with MySQL database but am encountering a lot of problems. First of all, the automatic upgrade fails with an error 'javax.servlet.jsp.JspException: java.lang.Exception: Failure while executing select * from jam_virtual_wiki' . I have Tomcat 6 installed with java 1.5 and fresh install works with any version.

Since the automatic upgrade fails I tried the manual upgrade to version 0.6.0 for starters, but with the same result. Then I tried to migrate the database from HSQLDB to MySQL using the MySQL Migration Toolkit but there are a lot of errors that get produced because of the quotes that are commented out. I could live with treating all the errors but all the links to files get lost also.

So my question: what is the easiest way to migrate from 0.5.1 to 0.7.1 without errors and keeping all my users data (which is quite a lot)?

Provided the steps on Installation#Upgrades are being followed then this should work, so I'll need to try to reproduce and see what's going on. The error you've provided above ("select * from jam_virtual_wiki") would seem to indicate that something failed at the start of the upgrade process which is unusual, so please do let me know if there is any step in the upgrade instructions that got overlooked. -- Ryan • (comments) • 20-Apr-2009 07:32 PDT

I'm quite sure I have not overlooked any of the upgrade instructions since I have done it four times now. I thought it might have to do with the database schema that gets changed in version 0.6.x so I started yesterday by trying out that release but with the same result.

First I tried the automatic upgrade using the steps described in the UPGRADE.txt document.

 Back up all database and/or file data prior to upgrading.
 Back up the jamwiki.properties file and the logging.properties from the the /WEB-INF/classes/ directory.
 Change the necessary items in the properties file (home dir, upload dir, etc).
 Remove the old JAMWiki installation by deleting your existing JAMWiki web application.
 Install the new JAMWiki WAR file.
 Stop the application.
 Restore the files that were backed up to their previous locations under the /WEB-INF/ and /WEB-INF/classes/ directories.
 Restore the database files to the correct location overwriting the ones created by install.
 Start the application.
 Browse to the site which redirects to the upgrade
 Provide any login (sa without password, admin that I created, database user, root user) with the result as indicated.

At this moment I'm trying to install the same version with HSQLDB database exactly the same as the original server is configured, i.c. version 0.5.1. I followed this steps:

 New install of version 0.5.1. with internal database
 Stop application
 Copy jamwiki.properties and logging.properties to the correct directory (WEB-INF/classes)
 Copy all the database files
 Restart the application.

and I get the error: javax.servlet.jsp.JspException: java.lang.Exception: Failure while executing select * from jam_virtual_wiki

I really hope you can help out with this one.

I just tried installing 0.5.1 with HSQL and then upgrading to 0.7.1 and got the following error:
2009-04-21 20:51:31,859 SEVERE: org.jamwiki.db.WikiPreparedStatement - Failure while executing delete from jam_group_authorities where group_id = ?
java.sql.SQLException: Table not found in statement [delete from jam_group_authorities where group_id = ?]
I'll try to fix this for 0.7.2, but in the mean time if you want to upgrade you might try downloading 0.6.1 (or a similar version), upgrading to that version, and then upgrading from there to 0.7.1 (I didn't try that specifically, but suspect it might be more successful as the upgrade process will have less to do). Thanks for the bug report, and apologies for the problems. -- Ryan • (comments) • 21-Apr-2009 20:58 PDT Hello Ryan,

I've been playing around with the HSQL database and MySQL and using SQuirreL I was able to copy the tables from HSQL to MySQL without any trouble. So, next I installed version 0.6.1 as you indicated, copied the properties files to the correct folder and restarted the webserver. I get the upgrade page and provide the login. Following this it takes some time but this upgrade also crashes, with the following statement:

The upgrade has failed. Please see below and check the logs for any failure messages, and consult the UPGRADE.txt document for details on how to perform a manual upgrade. Please report this error at jamwiki.org and provide any relevant information in the bug report.

Added jam_group table Added jam_role table Added jam_role_map table Added basic wiki roles. Added basic wiki groups. Converted admin users to new role structure. Removed ROLE_DELETE Unable to complete upgrade to new JAMWiki version.: null

The tables get created and inserts are executed apparently. After some digging around in the database and comparing it to the manual upgrade procedure I've encountered the following:

In the ultimate step (upgrade from 0.6.0 to 0.6.1) the instruction

 2. Delete the unused ROLE_DELETE:
      a) Delete values from the jam_role_map table:
             DELETE from jam_role_map where role_name = 'ROLE_DELETE';
      b) Delete values from the jam_role table:
             DELETE from jam_role where role_name = 'ROLE_DELETE';

But these values don't exist in the tables so I imagine that this is where the upgrade procedure crashes. I then changed the version number in the properties file and got the site running in version 0.6.1 but my layout is gone and I get the error that StartingPoints doesn't exist.

How can I repair this?

I tried editing the StartingPoints page as indicated but apparently nothing gets saved.

Thanks for your help Ryan.

Eric (vs.eric@gmail.com)

Hello Ryan,

I just did an upgrade from version 0.6.1 to 0.7.1 with errors that I was able to solve, but still I get no layout, it seems that StyleSheet is somewhere ignored, lost or inaccesible. Furthermore, I get the mention that StartingPoints doesn't exist and I'm unable to create it. When I click to edit and enter my text it doesn't get saved.

Hello,

Back again with an update. I've managed to get the content over to the new database layout whilst maintaining the WIKI layout, not without problems I can say. Though all content is in the MySQL database I cannot seem to access any of it. When I edit the LeftMenu as in the 'old' version all links show in red and when I click on a link it says the topic doesn't exist and I can create it.

How do the topics and versions link in the database to this LeftMenu? Is it only by the topic name or how? I cannot find anything that helps me any further on this one. Please enlighten me a bit.

Thanks for all of your patience - I've been traveling and otherwise busy and haven't had a chance to address these issues, so I apologize. The parser will use the topic name (jam_topic.topic_name) and virtual wiki (jam_topic.virtual_wiki_id) to do lookups against parsed text, and if no matching link is found then it will assume the topic does not exist and the link will appear red. For performance reasons there is also a caching layer present, so it may be possible that while your content exists an older version is cached - the cache can be cleared from Special:Maintenance#cache.
I definitely plan on giving this problem some attention prior to releasing 0.7.2... I did a number of upgrade tests for 0.7.0 without issue, but apparently most of them were from more recent JAMWiki versions. In the mean time the info you've provided (and your patience!) has been very much appreciated. -- Ryan • (comments) • 04-May-2009 07:16 PDT

No problem whatsoever Ryan, I'm glad you can find the time to help out on this issue because I'm really in the dark about what is going wrong. I just tried your solution clearing the cache but without result. The links stay red although all the data is in the database. It seems like Jamwiki cannot find anything. I have about 772 lines in jam_topic, 10232 in jam_topic_version but only 8 in jam_recent_change although I have over 10000 lines in the mysqldump. Is this normal? Does this table get cleaned with the clear cache command?

With revision 2586 I'm now able to upgrade from version 0.5.1 to 0.7.2 using HSQL on my Windows laptop. Previously the upgrade was attempting to set up group roles in a table that didn't yet exist, and I suspect that failures cascaded from there. I don't know if this fix will solve all of your problems, but I suspect that using an automated upgrade (as opposed to a manual one) will be more reliable and may help. I need to do a bit more testing on this change and I'll then make it available as a beta download, but if you're feeling adventurous and willing to compile from source feel free to grab the latest code on the /branches/0.7.x branch, build the WAR and try it out. Thanks again for your patience. -- Ryan • (comments) • 05-May-2009 22:19 PDT

That sounds like great news Ryan, thanks a lot! I'll wait for you to provide the beta version and then I'll perform an automated upgrade on our live system using HSQL. I suppose that after that upgrade it'll be a lot easier to move the site to another server and change the database to MySQL. Again, thank you very much for your help. Do you have an idea about the time when you'll release the beta? Eric 06-May-2009.

If it works for you I can commit to getting a beta out by the end of the weekend - there are a few more fixes I'd like to get done, but nothing major so Sunday evening should be a completely reasonable goal. -- Ryan • (comments) • 06-May-2009 19:58 PDT

Fantastic Ryan! I'll be leaving for our German office this Saturday and won't be back until next Wednesday so don't speed up things just because of me. Anyway, again, thanks a million. Eric 07-May-09.

Latest News#AMWiki 0.7.2 Beta 1 has links to the downloads. I didn't get to do as much testing as I would have liked, and while it works for me when I try to upgrade from 0.5.1 you may have different issues, so I'd be grateful for any feedback. Hopefully it works for you! -- Ryan • (comments) • 10-May-2009 21:29 PDT

Hello again Ryan,

I'm happy to tell you that with the beta you provided I was able to perform the upgrade using the HSQL database from version 0.5.1 to 0.7.2 without any errors. The only thing that is failing persistently is the content of the database. I'm really losing my mind on this one. The database is there, the upgrade performed without any errors but I still only get the default as with a clean installation. Clearing the cache didn't solve anything. I have a database of 67Mb and nothing is showing on the wikipage. Could you help me out on this issue please because I don't know what's going on.

Can you send me your jamwiki.log file from the upgrade? You can either upload it to jamwiki.org, or email me (please zip first) at ryan dot holliday at gmail dot com. Without being able to reproduce the issue it's going to be tough to solve, so hopefully that will provide some insight. Sorry for the continued problems! -- Ryan • (comments) • 15-May-2009 06:19 PDT
I've emailed Eric directly, but for others encountering this problem there were two issues - one, earlier versions of JAMWiki required that logins were unique but did not enforce that they had to be unique in a case-insensitive manner. Second, for some reason HSQL hung when populating the characters_changed column for a very large data set. Hopefully these two issues won't affect many users so I'm not going to change the code and risk any regressions in the upgrade logic, but for anyone experiencing similar problems perhaps this discussion will help in finding some resolution. -- Ryan • (comments) • 31-May-2009 12:21 PDT

Cannot login with existing users after moving wiki

Whenever I log in with an existing user, I am getting the following error:

java.lang.NoClassDefFoundError
	at javax.crypto.SecretKeyFactory.getInstance(DashoA12275)
	at org.jamwiki.utils.Encryption.createKey(Encryption.java:148)
	at org.jamwiki.utils.Encryption.encrypt64(Encryption.java:58)
	at org.jamwiki.utils.Encryption.encrypt(Encryption.java:98)
 	(snip)

I just moved the wiki from Resin to WebSphere and finally to a second instance of Resin on a new host. I would be happy to simply delete the existing users so we can register again. There are only three users, including the admin user. Hard to do anything when the admin user cannot log in. Bob White 09-Jun-2009 09:49 PDT

That error should indicate a CLASSPATH problem rather than a data issue - javax.crypto.SecretKeyFactory is a part of the standard JDK, but for some reason it seems like your app server can't find it... I don't know if it will help, but this discussion sounds like a similar issue. -- Ryan • (comments) • 09-Jun-2009 12:07 PDT
Problem turns out to have been that I needed to use JRE 6, but was using JRE 5. Since there are other apps running on this server, I could not fix it the easy way by changing the JAVA_HOME environment variable to point to JRE 6. Instead, I had to reinstall the service (I'm running resin under Windows) and include a command line switch to designate JAVA_HOME.
resin -install -java_home "C:\Program Files\Java\jre6"
When running resin as a Windows service, the "Path to executable" shown in the service Properties page is something like
%RESIN_HOME%\resin.exe ... -java_home %JAVA_HOME% ... -java_home "C:\Program Files\Java\jre6"
Note that the switch -java_home is repeated, first with the environment variable definition of JAVA_HOME and again with the value that I had put on the end of the command line when I re-installed resin as a service. The value assigned in the second occurrence of the switch is the value passed to the program. It overrides the default.

To be clear, this was not at all a bug in JAMwiki, just a misconfiguration of caucho resin that affected JAMwiki in this way. Thanks for your help. Bob White 09-Jun-2009 16:27 PDT

Thanks for the followup - glad it's working! -- Ryan • (comments) • 10-Jun-2009 07:04 PDT

NoSuchMethodError after Installation

After the installation screen I get this error message (german) Ein unbekannter Systemfehler ist aufgetreten. Die Fehlermeldung lautet: java.lang.NoSuchMethodError: org.apache.commons.lang.StringUtils.length(Ljava/lang/String;)I.. I installed JamWiki on a Apache Geronimo 2.1.3 and a mssql connection over jtds.-- Fanninger Thomas • 02-Mar-2009 04:40 PST

The method in question is included in the /WEB-INF/lib/commons-lang-2.4.jar that is included by default with the JAMWiki distribution. I suspect you might have an older version of the commons-lang.jar file somewhere in your classpath that is overriding the JAMWiki version - can you see if Geronimo is including commons-lang.jar by default somewhere? Thanks for the report! -- Ryan • (comments) • 02-Mar-2009 07:25 PST
Hi, I found the solution. Here an example of a geronimo-web.xml.


<?xml version="1.0" encoding="UTF-8"?>

<web:web-app xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" 
             xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" 
             xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" 
             xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" 
             xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" 
             xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" 
             xmlns:pers="http://java.sun.com/xml/ns/persistence" 
             xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" 
             xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" 
             xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
    <dep:environment>
        <dep:moduleId>
            <dep:groupId>org</dep:groupId>
            <dep:artifactId>jamwiki</dep:artifactId>
            <dep:version>0.7</dep:version>
            <dep:type>war</dep:type>
        </dep:moduleId>
        <dep:dependencies>
            <dep:dependency>
                <dep:groupId>at.kages.lib</dep:groupId>
                <dep:artifactId>jtds</dep:artifactId>
                <dep:version>1.2.2</dep:version>
                <dep:type>jar</dep:type>
            </dep:dependency>
        </dep:dependencies>
        <dep:hidden-classes>
            <dep:filter>org.apache.commons.lang</dep:filter>
        </dep:hidden-classes>
    </dep:environment>
    <web:context-root>/wiki</web:context-root>
</web:web-app>


-- Fanninger Thomas • (comments) • 03-Mar-2009 01:20 PST
Thanks for following up, and thanks for the updates to the Installation guide! -- Ryan • (comments) • 03-Mar-2009 07:14 PST

MySQL Import

Hello, I'm having problems migrating from HSQL to MySQL, probably because my DB is soo big. I cannot export to CSV, neither use the migration script. When using the migration script from the Maintenance page, I get the following error:

 Changes HAVE NOT been saved
 An unknown system error has occurred. The error message is: Data truncation: Data too long for column 'version_content' 
 at row 1.

When trying to export to CSV I get an out of memory error. Could you indicate where the migration script is located so I can review and eventually adapt it to test? -- Eric 09-Jun-2009.

I'll try and reproduce as soon as possible. I know Postgres import should work but I haven't yet tried MySQL. -- Ryan • (comments) • 09-Jun-2009 12:34 PDT

Hi Ryan,

I got it working! Successfully migrated from HSQL to MySQL using the MySQL Migration Toolkit and changing a lot of table options in the scripts and data. Basically the indices from HSQL do not get translated and are unusable with the MySQL install of Jamwiki resulting in not displaying any data in the wiki. Also the foreign keys need to be deleted if using MyISAM. Most important thing is that it's working great! Thank you for all your assistance over the last weeks. If you want the exact procedure please let me know and I'll be happy to provide it. Eric 11-06-09 11:10.

Migration Error

Copied from Tech:Migrate Database:

Any success with PostgreSQL? I have been able to export. But loading (migrating) is returning with no success and errors:

Changes HAVE NOT been saved
An unknown system error has occurred. The error message is: Failure while executing CREATE TABLE jam_virtual_wiki ( virtual_wiki_id INTEGER NOT NULL, virtual_wiki_name VARCHAR(100) NOT NULL, default_topic_name VARCHAR(200) NOT NULL, create_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT jam_p_vwiki PRIMARY KEY (virtual_wiki_id), CONSTRAINT jam_u_vwiki_name UNIQUE (virtual_wiki_name) ).
An unknown system error has occurred. The error message is: ERROR: relation "jam_wiki_user" does not exist.

Not exactly sure where the problem is happening. I have been looking at the code for org.jamwiki.db.WikiDatabase to see if there is a clue that can be found, but nothing like a smoking gun. Hoping there has been some success. I'm running 0.6.7, psql 8.2.5. --Tim

I believe that this issue is fixed for JAMWiki 0.7.0. -- Ryan • (comments) • 24-Feb-2009 20:00 PST