Pencarian

Rss Posts

 

 

 

Berita pada kategori ‘Sindikasi’

Year 7DB!

Jan 03, 2011

OK, yes, I was kinda sad enough at the end of December to convert 2011 to hex to find it is 7DB.? Which I think is appropriate as for me at least this will be the year of Drizzle7 DBMS.
It may be the winter holiday season but many of us Drizzle developers haven’t taken much of a break.? I have been working hard to keep our bug count down and will be working on some really cool new features this month.? Brian Aker has also announced things that he has been working on in this mailing list post.
So, what can you expect from the Drizzle project in year 7DB?? Here is a sneak preview of a few things off the top of my head (I really hope I haven’t missed anyone here):

Completion of replication support (thanks to David Shrewsbury, Joe Daly and everyone else involved there)
Many bugs killed (thanks as always to Patrick Crews for making our jobs that much harder by finding the bugs ? We have also have a bug killing week later this month.
Support for a few more data types (and probably improved support for current types)
Catalogs support
Improvements to system variables and options (thanks to Monty Taylor and Vijay Samuel)
InnoDB 1.1.4 (in fact, it has already been merged in, thanks to Stewart Smith)
Some really rocking documentation taking shape (thanks to our new documentation writer Marisa Plumb)
Some O’Reilly MySQL Conference and Expo talks (I will be there, details in another blog post soon)
Drizzle 7 GA release

And much of this will be done very early on this year. Development is happening at a very rapid pace and have made some great achievements so far.? As always we love to for you to try the source or our binaries and love to hear feedback.? We have had some fantastic feedback so far which has led to very rapid fixes and improvements in various areas.

New Leonardo Sketch Release: Ruby Red Remixed

Jan 02, 2011

Josh Marinacci has announced that a new version of Leonardo Sketch is now available: Ruby Red Remixed. Leonardo is:

an open source vector drawing program named after the 15th century painter, but aimed for the 21st century user. It focuses on common tasks like mockups, prototyping, quick vector sketches, and presentations with a clean and consistent user interface. Leo is designed to be augmented by internet webservices and plugins created in several scripting languages.

Ruby Red Remixed is an interim release along the path to the next major Leonardo release, Glowing Green. The release was pushed out to make the recent progress on the Leonardo platform available to the community, within the context of a formal, stable version. Ruby Red Revisited includes “tons of bug fixes,” as well as many significant new features.

Key new features include:

  • Infinite Canvas: The canvas will automatically grow as you add new objects to your drawing, even if they are beyond the edges of the document. Never run out of space again.
  • Draggable guidelines: create guidelines by dragging them out from the ruler. Objects will snap to them automatically.
  • Flickr upload support: Now you can upload your creations directly to Flickr as well as Twitter.
  • Improved SVG Import: Lots of Illustrator symbols can be imported now by exporting them as SVG from Illustrator.
  • New Rectangle UI: set rectangle corner radius and gradients directly with handles instead of with a palette. Much easier to use.
  • Improved translations, including Japanese. Edit or create new translations easily using the debug menu in the preferences.

See Ruby Red Remixed for more details on the latest release, and visit the Leonardo Sketch home page for additional information about Leonardo, the underpinning Amino library, and more.


Java Today

JUG Chennai (India) celebrated the New Year with Java User Group – Chennai JUGChennai Unconference meet, 1st January 2011 at Adams Studio India:

Agenda: JVM Langauges ? Rajmahendra. * 10:10AM Program started with Devraj talk on Flex and Java; * 10:30AM Talk on JVM Langauges. Why JVM Languages, Idea behind, Pros and Cons,Different types of Languages and introduction Gorrvy, Scala, JRuby, Fantom. JavaFX Script; * 11:30AM Product of JVM Languages Grails,Gradle, Lift, Tales; * 12:30PM Grails and Grails Demo…

Alexis Moussine-Pouchkine reviews GlassFish in 2010 – What a year!

A lot has happened over the past 12 months! For the GlassFish team as for many people that came from Sun, it’s been a challenging, yet exciting year. It all started in January with…

Hildeberto Mendon?a has a 2011 New Year’s Resolution – CEJUG: Commitment with My Homeland -

I will start this post making a promise for 2011: I will write at least a post per week in this blog. Last year I could not keep that promise because it was one of the toughest years for me. 2010 was the year of conclusions and analysis of future steps. I was in the last year of the PhD and I spent almost the whole year thinking about what to do next…

Jean-Fran?ois Bonbhel announces JCertif 2011 the biggest Java Community Event in Central Africa ! Save the dates : 27-28 August 2011 -

Hi All, I’ll like to let you know the dates of JCertif 2011 the biggest Java Community Event in Africa. About 800+ attendees from many countries.
We will be happy to have you as Speaker on Developer Tools, Java, Open Source, Mobile Apps…or Business solutions. tools. Still hesitating to join JCertif 2011 ? See The past event : JCertif 2010 and this blog post


Spotlights

Our latest java.net href="http://www.java.net/archive/spotlight">Spotlight is Micha Kops’ latest article, Enterprise Java Bean / EJB 3.1 Testing using Maven and embedded Glassfish:

Are you playing around with the shiny new 3.1 EJBs? Using Maven for your Java projects? Need an easy way to write and execute tests for your EJBs that depends on an Java Application Server? No problem using Maven Archetypes, the Maven EJB Plugin and the GlassFish embedded Application Container…

We’re also featuring JUG Chennai’s online newspaper, The JavaUserGroupChennai Daily. Recent headlines included New Year’s Eve wishes, a 2011 Android wish list, an article on SOA and MDM, and “Java EE Productivity Report 2011.”


Poll

Our current java.net poll asks Are you more optimistic today about Java’s future than you were a year ago? Voting will be open until Monday.


Subscriptions and Archives: You can subscribe to this blog using the java.net Editor’s Blog Feed. You can also subscribe to the Java Today RSS feed and the java.net blogs feed. You can find historical archives of what has appeared the front page of java.net in the java.net home page archive.

Kevin Farnham

Twitter: @kevin_farnham

Kai Toedter: Dynamic modular Web Applications with Vaadin and OSGi

Jan 02, 2011

I am a big fan of both OSGi and GWT (Google Web Toolkit). Unfortunately these two technologies don?t fit together very well. When you want to run OSGi on the server, RAP (Rich Ajax Platform) is one proven approach to go. While I like RAP a lot, you have to have quite a lot of Eclipse RCP know how for using it. Another alternative, if your want to run OSGi on the server and provide a modular, dynamic UI is Vaadin. Btw, Vaadin is the Finnish word for female reindeer. Vaadin is a server side RIA framework that uses GWT as rendering engine. In the last couple of days a played a bit around with Vaadin and I have to admit, I like it a lot. So, I wrote a little dynamic OSGi Vaadin demo (Download link and instructions are below). My goals for the demo were:

  • Provide Bundles that contribute directly to the web application?s UI
  • Just starting and stopping bundles should contribute/remove UI elements and functionality
  • I wanted to implement something similar to my dynamic Swing OSGi demo

Before I started with Vaadin, I found a few interesting reads and code sample regarding OSGi and Vaadin:

But back to the demo, here is a screen shot running the application in Firefox:

The idea is to support two kinds of UI contributions: views and actions. The views are inserted in a tab folder, the actions appear in the toolbar and the Action menu. I implemented a little OSGi agent as a view (Bundle View). This view shows a selection of bundles currently available. By checking/unchecking a bundle, it will be activated/stopped on the server side. If you press ?Deselect All?, all bundles go to resolved state and all the UI contributions disappear immediately:

Of course you could start and stop bundles from the OSGi console directly, then you would have to refresh the browser to get the changes displayed. To get the demo running on your local machine, follow these steps:

  • Make sure you have an Eclipse IDE installed
  • Download the demo sources and target platform osgi-vaadin-demo.zip (6.8 MB)
  • Import all projects from the zip file into Eclipse
  • Open the project ?com.siemens.ct.osgi.vaadin.target?
  • Double-click vaadin.target (That opens the target platform definition in an editor)
  • Click on ?Set as Target Platform? in the right top corner of the editor
  • Now everything should compile
  • Start the Run Configuration ?OSGi Vaadin Demo?
  • Open the following URL in your favorite browser ?http://localhost/com.siemens.ct.osgi.vaadin.pm.main?
  • If everything went well, you see the demo in your browser
  • Play around with it, activate/stop bundles and watch the console log

In the next weeks I plan to go a little bit more into details of the demo, how OSGi declarative services are used, how to contribute to Vaadin Themes, etc.

Stay tuned and have fun!

Kai

Follow me on Twitter

flattr this!

Jamis Buck: Maze Generation: Eller’s Algorithm

Dec 30, 2010

Last time I talked about the recursive backtracker algorithm for maze generation. That?s probably always going to be my favorite algorithm for generating mazes, for a variety of reasons, but that?s not going to stop me from looking at others.

For one thing, there are some pretty crazy algorithms out there for generating mazes.

Eller?s algorithm is one of the craziest. It?s also one of the fastest. And it?s the only one I know that let?s you generate mazes of an infinite size. In linear time.

Yeah, it?s that crazy.

It does this by building the maze one row at a time, using sets to keep track of which columns are ultimately connected. But it never needs to look at more than a single row, and when it finishes, it always produces a perfect maze.

Like I did for the recursive backtracking algorithm, here?s the ?mile-high? overview of Eller?s algorithm:

  1. Initialize the cells of the first row to each exist in their own set.
  2. Now, randomly join adjacent cells, but only if they are not in the same set. When joining adjacent cells, merge the cells of both sets into a single set, indicating that all cells in both sets are now connected (there is a path that connects any two cells in the set).
  3. For each set, randomly create vertical connections downward to the next row. Each remaining set must have at least one vertical connection. The cells in the next row thus connected must share the set of the cell above them.
  4. Flesh out the next row by putting any remaining cells into their own sets.
  5. Repeat until the last row is reached.
  6. For the last row, join all adjacent cells that do not share a set, and omit the vertical connections, and you?re done!

If you?re at all like me, your head is probably spinning at this point. Let?s back up and work through an example manually, to help you see how the algorithm works in practice. Let?s begin with a simple 5-column row.

An example

First, we initialize each cell in that row to be in its own set. I?ll just assign each cell a number, indicating the set it belongs to:

   ___________________
  |   |   |   |   |   |
  | 1 | 2 | 3 | 4 | 5 |
  |___|___|___|___|___|

Next, we randomly join adjacent cells that belong to different sets. The cells so joined also are merged into the same set:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |___________|_______|

Now we randomly determine the vertical connections, at least one per set. The cells in the next row that we connected to must be assigned to the set of the cell above them:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
  |   |   |   |   |   |
  | 1 |   | 1 |   | 4 |
  |___|   |___|   |___|

Next, we flesh out the next row, assigning each remaining cell to its own set:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
  |   |   |   |   |   |
  | 1 | 6 | 1 | 7 | 4 |
  |___|___|___|___|___|

At this point, we can actually discard the first row, because the algorithm is done with it. We?ll keep it around for now, though, for the sake of illustration. I?ll just put a little space between the previous rows, and the current row:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
       ___     ___
  |   |   |   |   |   |
  | 1 | 6 | 1 | 7 | 4 |
  |___|___|___|___|___|

Now, we just repeat the previous steps on our new row. We randomly connect adjacent sets that do not share a set. Something like this:

       ___     ___
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |_______|_______|___|

Now we add at least one vertical connection for each set:

       ___     ___
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |___    |_______|   |
      |   |       |   |
      | 1 |       | 4 |
      |___|       |___|

And then we flesh out the next row (I?m reusing some extinct set numbers here, for the sake of single-digits):

       ___     ___
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |___    |_______|   |
  |   |   |   |   |   |
  | 8 | 1 | 9 | 2 | 4 |
  |___|___|___|___|___|

This is our current state, with history, now:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |___    |_______|   |
   ___     ___ ___
  |   |   |   |   |   |
  | 8 | 1 | 9 | 2 | 4 |
  |___|___|___|___|___|

It?s starting to look like a maze! Let?s do one more iteration, and then finish it out. So, first, randomly join adjacent cells from different sets:

   ___     ___ ___
  |   |   |           |
  | 8 | 1 | 9   9   9 |
  |___|___|___ ___ ___|

Then, add at least one veritcal connection for each set:

   ___     ___ ___
  |   |   |           |
  | 8 | 1 | 9   9   9 |
  |   |   |___     ___|
  |   |   |   |   |
  | 8 | 1 |   | 9 |
  |___|___|   |___|

And flesh out the next row:

   ___________________
  |           |       |
  | 1   1   1 | 9   9 |
  |    ___    |___    |
  |       |       |   |
  | 1   1 | 1   1 | 9 |
  |___    |_______|   |
  |   |   |           |
  | 8 | 1 | 9   9   9 |
  |   |   |___     ___|
           ___     ___
  |   |   |   |   |   |
  | 8 | 1 | 3 | 9 | 5 |
  |___|___|___|___|___|

And now the last row. This time, we must connect ALL adjacent (but disjoint) cells. In this case, that means all of them:

           ___     ___
  |                   |
  | 8   8   8   8   8 |
  |___________________|

Since this is the last row, we skip the bit where we add verticals?and that means we?re done! The result, with set numbers removed, is:

   ___________________
  |           |       |
  |           |       |
  |    ___    |___    |
  |       |       |   |
  |       |       |   |
  |___    |_______|   |
  |   |   |           |
  |   |   |           |
  |   |   |___     ___|
  |                   |
  |                   |
  |___________________|

A perfect maze!

Analysis

Let?s analyze that a bit. It seemed to come together pretty magically, considering we weren?t looking at anything but the current row (and the next row, briefly). The key to it all are the sets.

The set that a cell belongs to tells the algorithm who its siblings were, are, and will be. It?s the crystal ball that lets the algorithm gaze into the future (and the past!) and avoid adding cycles and isolates to the maze.

Cells that share a set, also share a path between them. (If you don?t believe me, look at the example I just gave, above. Every cell that shares a set identifier is connected; cells in different sets are not connected.)

If the algorithm allowed us to create a passage between two cells that shared a set, it would be introducing a second path between those two cells. That?s essentially the definition of a loop or cycle in the graph, and since we don?t want cycles in our maze, we disallow that.

Conversely, cells that do not share a set, are not connected (they are disjoint). By the time we reach the end of the maze, every cell must be connected to every other cell, and the only way we can do that is if every set is eventually merged into a single set.

We can?t do that if a set does not propogate itself to the next row. This is why the algorithm requires that at least one vertical passage be created for each set in the row. Otherwise, any set that didn?t create a vertical passage would become extinct after the current row. The result would be an isolate, an orphaned collection of cells that could never be reached from outside that set.

Then, at the end, the algorithm joins all disjoint sets, allowing every cell in the the entire maze to be connected by a single, unique path to any other cell in the maze. And we?re done!

Implementation

How would you implement this? The key, for me, turned out to be implementing the sets. You need to be able to quickly determine the set of any given cell in a row, as well as determine the list of cells in any given set. I did this by maintaining a hash of arrays that mapped sets to cells, and another hash that mapped cells to sets. As I did in the example above, I simply used a unique integer to identify each set.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@sets = Hash.new { |h,k| h[k] = [] }
@cells = {}

def same?(cell1, cell2)
  @cells[cell1] == @cells[cell2]
end

def add(cell, set)
  @cells[cell] = set
  @sets[set] << cell
  self
end

def each_set
  @sets.each do |id, set|
    yield id, set
  end
end

The process of merging two sets is O(n) as I?ve implemented it, but given that n is fairly small, that didn?t worry me too much:

1
2
3
4
5
6
7
def merge(sink_cell, target_cell)
  sink, target = @cells[sink_cell], @cells[target_cell]

  @sets[sink].concat(@sets[target])
  @sets[target].each { |cell| @cells[cell] = sink }
  @sets.delete(target)
end

There?s plenty of room for optimization there, though.

Lastly, assigning set ids is done via a #populate method:

1
2
3
4
5
6
7
8
9
10
11
def populate
  width.times do |cell|
    unless @cells[cell]
      set = @next_set += 1
      @sets[set] << cell
      @cells[cell] = set
    end
  end

  self
end

Once I had these routines (encapsulated into a State class), the algorithm itself came fairly neatly. It works in two steps, plus a third to convert the representation into something easier to display.

The first step looks over the row and randomly connects adjacent cells (if they exist in disjoint sets):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
connected_sets = []
connected_set = [0]

(state.width-1).times do |c|
  if state.same?(c, c+1) || (!finish && rand(2) > 0)
    # cells are not joined by a passage, so we start a new connected set
    connected_sets << connected_set
    connected_set = [c+1]
  else
    state.merge(c, c+1)
    connected_set << c+1
  end
end

connected_sets << connected_set

As you can see, the process simply looks at each cell and its neighbor, comparing their states and then either adding the cells to a ?connected set? (a series of adjacent cells that are all horizontally connected) and merging the sets together, or creating a new connected set when the two cells should not be merged.

The finish variable is used to change the behavior for the final row; it is false for the rest of the rows.

The second step looks at the available sets and randomly adds vertical connections:

1
2
3
4
5
6
7
8
9
10
verticals = []
next_state = state.next

unless finish
  state.each_set do |id, set|
    cells_to_connect = set.sort_by { rand }[0, 1 + rand(set.length-1)]
    verticals.concat(cells_to_connect)
    cells_to_connect.each { |cell| next_state.add(cell, id) }
  end
end

State#next just returns a new State object (that we?re using for the next row). Then, for each set of cells, we randomly pick some number of them and add them to the list of verticals we?re going to create. (The verticals are also added to the next row, in the same set.)

The algorithm itself then loops over these steps repeatedly, setting state to next_state at the end of each pass, until it is done. (In my case, I trapped the INT signal, so ctrl-C can be used to terminate the algorithm and gracefully finish the maze.)

My complete implementation is here:

<noscript>ellers.rb on gist.github.com</noscript>

I think Eller?s algorithm is harder to customize than the recursive backtracking algorithm, but it can be done. Consider it an exercise, if you want: how would you introduce horizontal or vertical bias into the maze? (I.e., how would you make the maze prefer longer corridors, either horizontally or vertically?) How would you implement weave mazes, where the passages move over or under other passages? Especially tricky: how would you introduce symmetry into the output, given that the algorithm itself doesn?t look at anything more than the single row?

If nothing else, though, please give Eller?s algorithm a shot. Please share your implementations (in any language!) in the comments (links to gist.github.com are preferred).

MySQL NUMA allocations under 2.6.32+

Dec 30, 2010

refering Jeremy Cole’s post on swapstorming under NUMA hardware, I’ll note something potentially new.While I’ve seen this “brick wall swapstorming” a few times before and since the post, I just saw some new OS installs not do this by default, and using the numactl to change the defaults is actually harmful to system interactivity.In the brick-wall cases, two NUMA zones of ~30G each, plus a mysqld (or memcached) running with 45G of ram, would equal 30G in memory, and 15G in swap. Ugly.In this case, I’m getting a little bit in swap, but a relatively even note dist.Here’s a box with no numactl tuning:
N0 : 7068733 ( 26.97 GB)
N1 : 7120258 ( 27.16 GB)
active : 13355529 ( 50.95 GB)
anon : 14187441 ( 54.12 GB)
dirty : 14185099 ( 54.11 GB)
mapmax : 265 ( 0.00 GB)
mapped : 1580 ( 0.01 GB)
swapcache : 2350 ( 0.01 GB)
similar hardware, same OS/kernel running under numactl –interleave=all:
N0 : 6778742 ( 25.86 GB)
N1 : 6313382 ( 24.08 GB)
active : 12395957 ( 47.29 GB)
anon : 13090566 ( 49.94 GB)
dirty : 13090566 ( 49.94 GB)
mapmax : 255 ( 0.00 GB)
mapped : 1588 ( 0.01 GB)
… just a touch in swap on the first guy. Though I’m going to wait a few days to declare victory or defeat, since I did see the first guy dump nearly a whole gig of swap once, but wasn’t able to confirm if the swapped memory was mysql yet.The side note here is that my numactl-modified node is exhibiting some extreme latency on interactivity. Appears to be related to anything that needs to fork having a half-second delay. MySQL seems to be running fine though.I haven’t investigated at all as to how numa distribution has changed in recent kernels (though I know it’s been steadily improving over the years). Unfortunately every other box I’ve used which *has* the problem, runs on a redhat/centos5 kernel. Which is ancient to an extreme.In this case it’s debian squeeze with its default 2.6.32 kernel. Anyone try a recent ubuntu or redhat6 yet and see if the NUMA/swap issues are better on there?

Hendy Irawan: Activating the EMF Edit ItemProvider AdapterFactory-s (with CDO)

Dec 30, 2010

I used to have a problem with CDO Editor UI: it does not use my EMF Edit models’ ItemProvider implementation (like label formatting, image/icon, and so on).

Today I found the reason, I changed the model’s nsURI and did not change all references to it.

The relevant portion is plugin.xml for your.model.edit plugin :

?? <extension point="org.eclipse.emf.edit.itemProviderAdapterFactories">
????? <factory
??????????? uri="
http://www.abispulsa.com/model/1.0"
??????????? class="com.abispulsa.provider.AbispulsaItemProviderAdapterFactory"
??????????? supportedTypes=
????????????? "org.eclipse.emf.edit.provider.IEditingDomainItemProvider
?????????????? org.eclipse.emf.edit.provider.IStructuredItemContentProvider
?????????????? org.eclipse.emf.edit.provider.ITreeItemContentProvider
?????????????? org.eclipse.emf.edit.provider.IItemLabelProvider
?????????????? org.eclipse.emf.edit.provider.IItemPropertySource"/>
?? </extension>

The way to get ComposedAdapterFactory I previously blogged turned out to be incorrect:

public class AbispulsaContentProvider extends AdapterFactoryContentProvider {

private static AdapterFactory adapterFactory;

static {
adapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
new ResourceItemProviderAdapterFactory(),
new AbispulsaItemProviderAdapterFactory(),
new ReflectiveItemProviderAdapterFactory()
});
}

public AbispulsaContentProvider() {
super(adapterFactory);
}

}

The correct way is like this:

public class AbispulsaContentProvider extends AdapterFactoryContentProvider {

private static ComposedAdapterFactory adapterFactory;

static {
Registry registry = EMFEditPlugin.getComposedAdapterFactoryDescriptorRegistry();
adapterFactory = new ComposedAdapterFactory(registry);
adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
}

public AbispulsaContentProvider() {
super(adapterFactory);
}

}

Although then you should move the ComposedAdapterFactory creation to another singleton class so it can be reused from both ContentProvider and LabelProvider.

Note that for above to work, the extension org.eclipse.emf.edit.itemProviderAdapterFactories must also be set properly.

This is actually not CDO specific, but applies to all EMF Edit / Editor UI in general.
But it highlights a very important CDO feature: it reuses your EMF Edit ItemProvider implementations! :-)

Hendy Irawan: How to Dump/Inspect Object or Variable in Java

Dec 26, 2010

Scala (console) has a very useful feature to inspect or dump variables / object values :

scala> def b = Map("name" -> "Yudha", "age" -> 27)
b: scala.collection.immutable.Map[java.lang.String,Any]

scala> b
res1: scala.collection.immutable.Map[java.lang.String,Any] = Map((name,Yudha), (age,27))

Inside our application, especially in Java programming language (although the techniques below obviously works with any JVM language like Scala and Groovy) sometimes we want to inspect/dump the content of an object/value. Probably for debugging or logging purposes.

My two favorite techniques is just to serialize the Java object to JSON and/or XML. An added benefit is that it’s possible to deserialize the dumped object representation back to an actual object if you want.

JSON Serialization with Jackson

Depend on Jackson (using Maven):
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.6.3</version>
</dependency>
Then use it:
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

..
Logger logger = LoggerFactory.getLogger(getClass());

@Test
public void level() throws ServiceException, JsonGenerationException, JsonMappingException, IOException {
MagentoServiceLocator locator = new MagentoServiceLocator();
Mage_Api_Model_Server_HandlerPortType port = locator.getMage_Api_Model_Server_HandlerPort();
String sessionId = port.login("...", "...");
logger.info(String.format("Session ID = %s", sessionId));
Map[] categories = (Map[]) port.call(sessionId, "catalog_category.level", new Object[] { null, null, 2 } );
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
logger.info( mapper.writeValueAsString(categories) );
}

Example output :

6883 [main] INFO id.co.bippo.shop.magentoclient.AppTest - [ {
? "position" : "1",
? "level" : "2",
? "is_active" : "1",
? "name" : "Gamis",
? "category_id" : "3",
? "parent_id" : 2
}, {
? "position" : "2",
? "level" : "2",
? "is_active" : "1",
? "name" : "Celana",
? "category_id" : "5",
? "parent_id" : 2
} ]

XML Serialization with XStream

As a pre-note, XStream can also handle JSON with either Jettison or its own JSON driver, however people usually prefer Jackson than XStream for JSON serialization.

Maven dependency for XStream:
<dependency>
<groupId>xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.2.2</version>
</dependency>
Use it:
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Map;

import javax.xml.rpc.ServiceException;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.thoughtworks.xstream.XStream;
...
@Test
public void infoXml() throws ServiceException, RemoteException {
MagentoServiceLocator locator = new MagentoServiceLocator();
Mage_Api_Model_Server_HandlerPortType port = locator.getMage_Api_Model_Server_HandlerPort();
String sessionId = port.login("...", "...");
logger.info(String.format("Session ID = %s", sessionId));
Map category = (Map) port.call(sessionId, "catalog_category.info",
new Object[] { 3 } );
XStream xstream = new XStream();
logger.info( xstream.toXML(category) );
}

Sample output:

5949 [main] INFO id.co.bippo.shop.magentoclient.AppTest - <map>
? <entry>
??? <string>position</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>custom_design</string>
??? <string></string>
? </entry>
? <entry>
??? <string>custom_use_parent_settings</string>
??? <string>0</string>
? </entry>
? <entry>
??? <string>custom_layout_update</string>
??? <string></string>
? </entry>
? <entry>
??? <string>include_in_menu</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>custom_apply_to_products</string>
??? <string>0</string>
? </entry>
? <entry>
??? <string>meta_keywords</string>
??? <string>gamis, busana muslim</string>
? </entry>
? <entry>
??? <string>available_sort_by</string>
??? <string></string>
? </entry>
? <entry>
??? <string>url_path</string>
??? <string>gamis.html</string>
? </entry>
? <entry>
??? <string>children</string>
??? <string></string>
? </entry>
? <entry>
??? <string>landing_page</string>
??? <null/>
? </entry>
? <entry>
??? <string>display_mode</string>
??? <string>PRODUCTS</string>
? </entry>
? <entry>
??? <string>level</string>
??? <string>2</string>
? </entry>
? <entry>
??? <string>description</string>
??? <string>Gamis untuk muslimah</string>
? </entry>
? <entry>
??? <string>name</string>
??? <string>Gamis</string>
? </entry>
? <entry>
??? <string>path</string>
??? <string>1/2/3</string>
? </entry>
? <entry>
??? <string>created_at</string>
??? <string>2010-12-24 11:37:41</string>
? </entry>
? <entry>
??? <string>children_count</string>
??? <string>0</string>
? </entry>
? <entry>
??? <string>is_anchor</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>url_key</string>
??? <string>gamis</string>
? </entry>
? <entry>
??? <string>parent_id</string>
??? <int>2</int>
? </entry>
? <entry>
??? <string>filter_price_range</string>
??? <null/>
? </entry>
? <entry>
??? <string>all_children</string>
??? <string>3</string>
? </entry>
? <entry>
??? <string>is_active</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>page_layout</string>
??? <string></string>
? </entry>
? <entry>
??? <string>image</string>
??? <null/>
? </entry>
? <entry>
??? <string>category_id</string>
??? <string>3</string>
? </entry>
? <entry>
??? <string>default_sort_by</string>
??? <null/>
? </entry>
? <entry>
??? <string>custom_design_from</string>
??? <null/>
? </entry>
? <entry>
??? <string>updated_at</string>
??? <string>2010-12-24 11:37:41</string>
? </entry>
? <entry>
??? <string>meta_description</string>
??? <string>Jual baju gamis untuk muslim</string>
? </entry>
? <entry>
??? <string>custom_design_to</string>
??? <null/>
? </entry>
? <entry>
??? <string>path_in_store</string>
??? <null/>
? </entry>
? <entry>
??? <string>meta_title</string>
??? <string>Gamis</string>
? </entry>
? <entry>
??? <string>increment_id</string>
??? <null/>
? </entry>
</map>

Which one is better?

I personally prefer JSON, but fortunately, you always have a choice. :-)

Ubuntu Upstart for automatic MySQL start and stop

Dec 25, 2010

Here at Recorded Future we use Ubuntu (running on Amazon EC2), but so far we have not explored Ubuntu Upstart that much. During the holidays I made an effort to get acquainted with Upstart and to implement proper MySQL start and stop with it.If you do not know Upstart, this is the way you start and stop services in Ubuntu, and it serves the same purpose as the old /etc/init.d scripts, but are a bit more structured and powerful. That said, Upstart is regrettably far from complete, although the functionality is much better and Upstart has some cool features, some things do not work that well. For one thing, documentation, where it exists, is useless, at best. Secondly, there is very limited ability to test and develop Upstart scripts. And this is made worse by the fact that the documentation is so bad. Another thing is that Upstart insist on stopping services, by default, by sending a brutal kill signal. Not good for databases, mostly.In the /etc/init directory are the Upstart scripts you have. In difference to the old init.d scripts, you cannot disable a service in Upstart curenntly. If it is in /etc/init it will be started at system start. That’s it. And this is something that I am sure will be fixed, but for now, again, is something we have to live with. Upstart scripts have the suffix .conf (don’t ask me why), so the default MySQL Upstart script, for example, is called /etc/init/mysql.conf.In an Upstart script, there are Stanzas that determine what to do. Like the exec Stanza that runs a program for example. And you may then ask, when is it run? Startup? Shutdown? And the answer is startup. For shutting things down, as I said before, Upstart will by default just send a kill -9 signal.The minimal startup script you can have, and this actually works in a reasonable way, is to just have one line with an exec stanza, like this:exec /usr/bin/mydaemonWhich will start the daemon. For stopping the daemon, Upstart will send a -9 signal to the started process by default, and nothing more is needed in the Upstart script.For MySQL, we need to make things a bit more complicated. The default mysql.conf Upstart script really is not good. For one thing, it will not do a controlled shutdown of MySQL (this is possible even if Upstart will eventually send a kill -9 anyway). Secondly, this script assumes that what we use is a standard Ubunty installed MySQL distribution, so if you have installed MySQL in /usr/bin/mysql5147 or somethings like that, you are out of luck.So what I wanted to create was an Upstart script for MySQL that fullfilled these requirements:Starts MySQL automatically.Waits for MySQL to be available before exiting.Be configurable to support different MySQL install locations, data directories etc.Do a clean shutdown of MySQL when stopping the MySQL services.Before I show you what I ended up with, I want to comment on the points 2 and 4 above. With Upstart, you can define a script or command to run just before or after a services has been started or stopped, and this is what I use to wait for MySQL to become available, and to send a SIGTERM to the MySQL Server when stopping (which will do a clean MySQL shutdown).So here we go, a complete MySQL Upstart script, the way I want it to work:## MySQL Service for Recorded Future#description “MySQL Server”author “Anders Karlsson, Recorded Future”start on (net-device-up and local-filesystems and runlevel [2345])stop on runlevel [016]expect forkkill timeout 2# Set variables.env MYSQL_ETC=/etc/mysqlenv MYSQL_PIDFILE=/var/run/mysql.pidenv MYSQL_HOME=/usr/local/mysql5.5env MYSQL_INSTANCE=myumask 007exec $MYSQL_HOME/bin/mysqld_safe –defaults-file=$MYSQL_ETC/$MYSQL_INSTANCE.cnf >> /tmp/x.out &post-start script loop=600# Wait for MySQL to start. while [ $loop -gt 0 ]; do if $MYSQL_HOME/bin/mysqladmin –defaults-file=$MYSQL_ETC/$MYSQL_INSTANCE.cnf ping; then break fi loop=$(($loop – 1)) sleep 1 done exit 0end script# Send a soft SIGTERM to MySQL before Upstart will kill it.# A Sigterm to mysqld will cause a controlled shutdown.pre-stop script exec kill -SIGTERM `cat $MYSQL_PIDFILE`# Wait for MySQL to end. Flushing buffers and all. loop=600 while [ $loop -gt 0 ]; do# If the pidfile is found, then continue waiting. if [ -e $MYSQL_PIDFILE ] ; then loop=$((loop – 1)) sleep 1 continue fi break doneend scriptTo be honest, this is not what I create for all our MySQL servers. Instead I used this to create a chef template, chef is what we use for configuration management here (see http://www.opscode.com/ for more on chef), and here it is put to good ude to generate an Upstart script for MySQL. The above is just an example./Karlsson

Proposal for MariaDB trademark policy

Dec 21, 2010

Within Monty Program Ab we have during this year had a lot of discussions about how to go forward with the MariaDB trademark. It’s been clear that everyone wants to have something that is substantially freer than the MySQL trademark to ensure the survival of MariaDB whatever happens to Monty Program Ab.We wanted to make something that should work well, both for open source and commercial usage (and yes, I know that in some cases these are one and the same), which is not very common with many other trademark policies. My belief is that by having a very liberal trademark policy we will create a bigger ecosystem around MariaDB which will help all of us.Now we have had a couple of internal drafts (with heavy input from our community advocates) and we have released our first public draft.Please give us feedback about this either on my blog or the knowledge base so that we can take your thoughts into account for our final version!

Web2project v2.2 Release Notes – Keith Casey

Dec 21, 2010

web2project homepageAs of 19 December 2010, web2project v2.2 is officially live! You can download it from SourceForge now.

While in many releases we might focus on cleanup or functionality or developer aspects or similar, this one is a mishmash of a bunch of useful updates on numerous fronts. This isn’t all of the updates but a bunch of the important ones:

For the Project Managers:

  • We reworked much of the Gantt Chart logic. We’ve added a few icons to better represent the status of tasks and milestones. To make the overall charts easier to understand, we’ve added a legend and shaded alternate lines.
  • Gantt Charts are now exportable as single-page PDFs. You can print, email, share, or whatever with just a click.
  • We updated Token Tasks – which represent Subprojects – have been updated to prevent direct editing. Further, more of the Subproject data synchronizes as expected.
  • Depedency Tracking is now ON by default. This will provide better cascading updates when Tasks move.

For System Admins:

  • If System Timezone or System Admin Email are not set, the system will provide warning messages with links to the specific fields in the System Admin screens.
  • If filesystem permissions are properly configured, the Module screen supports direct uploading.
  • The Reports module has a permissions check applied. Previously, it did not.. though the underlying data was filtered appropriately.
  • The core system supports configurable pagination for the Project List screen and a few others.

For Developers:

  • We replaced our old Javascript library (Mootools) with jQuery. It’s faster, easier to use, and widely supported.
  • Added approximately 40 Unit Tests covering areas such as CDate and other classes.
  • Added a call in the Calendar Module to display arbitrary date-related information. A reference implementation is coming in the next release.

For General Users:

  • We’ve added Czech and Russian translations. If the dice rolls work out, we’ll move to Kamchatka next.
  • We’ve set the field focus to the first text box on each screen.
  • Private Tasks are now respected on all screens including Gantt Charts.
  • We fixed a number of visual issues.

Finally, special thanks goes to community member Opto who consistently submits great bug reports, shares useful patches, and provides random insights that help and speed things along. Thanks!

And that wraps our releases for 2010.

This year we managed 1 Major Release, 3 Minor Releases, and 1 Patch Release. Most of the releases were a week or two later than we wanted but we managed to get all of them out on schedule. More importantly, each and every release has managed to provide new functionality and close bugs while collecting and responding to community feedback.

And in case you missed our recent coverage on SourceForge, check it out!