Blog Taxonomy

Home

Contributing to Krita

kinow @ Jan 03, 2017 11:40:03 ()

As I mentioned in the last post, I have been learning Qt and using C and C++ again. Since I used C and C++ more during university (about 10 years ago, phew), decided to read real code.

I used Photoshop, Illustrator, and Fireworks a lot when I was younger and had more time to spend drawing. But some time ago I switched to Inkscape for vector graphics, which I use at work for presentations. So it was only natural to try Krita now.

Since I was going to try Krita, I thought why not check out and build from source, and then in case I found any bugs, contribute back? Or maybe from time to time triage issues, find low hanging ones, and send a patch?

Well, turns out the Krita project has a great community, and it is super easy to send contributions. So far I submitted three patches, some were included in 3.x releases.

While the patches are rather small, they are suggestions on how to fix memory segmentation faults, or strange behaviours in the interface. For these issues, I had to learn more about Qt components, signals and emitting events, and, of course, work with pointers, arrays, Qt data structures, etc. In other words, lots of (geek) fun!

In other words, by contributing to Krita, I am not only helping the project and giving a little back to the community, but also refreshing my memory on C and C++, and slowly learning Qt - which is not very hard if you worked with Swing/AWT, Delphi, Visual Basic, Gtk, etc.

What are you waiting to contribute to Krita? The developers that maintain the project answer tickets and questions posted to reddit in a good time, and are extremely easy to work with.

Read more here how to build from source, and here on how to submit patches.

Happy hacking!

Debugging an application that freezes the X server

kinow @ Jan 02, 2017 00:39:03 ()

Some time ago, I decided to start writing C++ again, and picked Krita for that. Krita is written in C++ and Qt. The bug I was working on involved a memory issue when changing the UI.

The problem was that this UI change would result in, not only Krita, but the whole X server freezing. My set up was basically Ubuntu 16.04.1 LTS, with Eclipse, Qt5, and the latest version of Krita checked out via git.

Initially I spent some time looking at the logs, tracing the binary, even downloaded some Qt utility tools to look at the events and what was happening with the application when it froze.

However, eventually I realized I was going to spend more time on this part of the issue, rather than on the memory bug. So decided to look for a work-around.

Thankfully someone else blogged about a similar issue and saved me a lot of time :-) Here’s how I did it, following the instructions in this blog post.

$ sudo apt-get install xnest -y
$ cd krita_install/
$ Xnest :10
$ twm -display :10
$ export DISPLAY=:10
$ ./krita

That’s it. You should have Krita running in a separate window, with Xnest, and within this window the twm window manager running. So when it freezes, at least you can still debug your application in Eclipse or whatever IDE you prefer.

Happy hacking!

Drawing sketch: Uh!

kinow @ Dec 19, 2016 19:40:03 ()

Sketch.

Uh! progress
Uh! progress

And final work here.

Uh!
Uh!

For redditgetsdrawn

PermGen errors and java.lang.ClassCastException: com.sun.crypto.provider.AESCipher cannot be cast to javax.crypto.CipherSpi running Jenkins plug-in tests with PowerMock

kinow @ Dec 19, 2016 19:20:03 ()

Recently while working on a Jenkins plugin some tests were failing with PermGen errors. Even though it worked in my notebook at home (with Java 8, thus no Permgen), it failed in a CloudBees hosted Jenkins job, and also on my Mac (with Java 7) at work.

As I could not change the settings in the CloudBees hosted Jenkins, I decided to spent some time investigating why these tests would require so much memory. Then I found this blog post about PowerMock.

I was not using the @PrepareForTest annotation, but after adding it the issue was gone. So I assume it either prevents PowerMock from trying to dynamically load several classes, or instructs it to unload classes after the tests. But in anyway after adding it the issue was gone.

Then I got the following exception.

WARNING: Failed to instantiate Key[type=hudson.security.csrf.DefaultCrumbIssuer$DescriptorImpl, annotation=[none]]; skipping this component
com.google.inject.ProvisionException: Guice provision errors:

1) Error injecting constructor, java.lang.ClassCastException: com.sun.crypto.provider.AESCipher cannot be cast to javax.crypto.CipherSpi
  at hudson.security.csrf.DefaultCrumbIssuer$DescriptorImpl.<init>(DefaultCrumbIssuer.java:127)

1 error
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:52)

And then thanks to this issue I understood that PowerMock was mocking javax.crypto classes. Turns out it is quite easy to tell PowerMock to ignore certain classes from being mocked, with the @PowerMockIgnore annotation.

// snip
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.crypto.*" })
public class TestAbstractUnoChoiceParameter {
//
}
// snip

Added a couple of notes to this Jenkins Wiki page so that users facing similar issues can try these possible workarounds.

Hope that helps someone!

Using Requests Session Objects for web scraping

kinow @ Nov 25, 2016 01:24:03 ()

I had to write a Python script some months ago, that would retrieve Solar energy data from a web site. It was basically a handful of HTTP calls, parse the response that was mainly in JSON, and store the results as JSON and CSV for processing later.

Since it was such a small task, I used the Requests module instead of a complete web scraper. The HTTP requests had to be made with a time out, and also pass certain headers. I started customizing each call, until I learned about the Requests Session Objects.

You create a session, as in ORM/JPA, where you can define a context, with certain properties and control an orthogonal behavior.

import requests

def get(session, url):
    """Utility method to HTTP GET a URL"""
    response = session.get(url, timeout=None)
    return response

def post(session, url, data):
    """Utility method to HTTP POST a URL with data parameters"""
    response = session.post(url, data=data, timeout=None)
    if response.status_code != requests.codes.ok:
        response.raise_for_status()
    return response

with requests.Session() as s:
    # x-test header will be sent with every request
    s.headers.update({'x-test': 'true'})

    data = {'user': user, 'password': password, 'rememberne': 'false'}
    r = post(s, 'https://portal.login.url', data)

    r = get(s, 'https://portal.home.url')

Besides the session object, that gives you ability to add headers to all requests, you won’t have to worry about redirects. The library by default takes care of that with a default limit of up to 30.

Happy hacking!