Blog

Posts about technology and arts.

Drawing sketch: Uh!

Sketch.

And final work here.

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

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

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!

Changing Spring Boot environment variables in the command line

This week while helping developers and testers to experiment with a backend application, some of them found useful to learn a simple trick to change Spring Boot properties when you can run the application locally (our testers build, compile, change the code, how cool is that?).

Here’s how it works. Say you have the following settings in your application’s application.properties:

my.application.database.username=sa
my.application.database.password=notasimplepassword

And that you want to change these parameters in order to, for instance, create an application error, so that you can code and test what happens to the frontend application in that situation.

You replace dots by underscores, and put all your words in upper case. So the variables above would be: MY_APPLICATION_DATABASE_USERNAME and MY_APPLICATION_DATABASE_PASSWORD.

Furthermore, you do not need to edit your application.properties file, if you are on Linux or Mac OS. You can start the application and override environment variables at the same time with the following syntax.

$ MY_APPLICATION_DATABASE_USERNAME=olivei MY_APPLICATION_DATABASE_PASSWORD=7655432222a mvn clean spring-boot:run

This way your application will start with the new values.

Happy hacking!

–EDIT–

As pointed by Stéphane Nicoll (thanks!), you could change the property values without having to use the upper case syntax.

mvn -Dmy.application.database.username=anotheruser clean spring-boot:run

And he even included a link to docs! ♥ the Internet and Open Source!

Add a header to a file with Shell script (sed)

Today I was re-generating the documentation for a REST API written in PHP, with Laravel. To generate the documentation, one would have to call a Laravel command first. That command would create a Markdown page. And since in this project I am using Jekyll for the project site, the final step was adding a header to the file, so that Jekyll can recognize that content as a blog post.

Laravel allows you to add custom commands to your project, so I decided to write a command that would call the other command that generates the documentation, and add an extra step of adding the header to the Markdown file.

Here’s the shell script part, that allows you to add a header to a file, in place (i.e. it will alter and save the change your file).

sed -i 1i"----\nlayout: page\ntitle: API Installation\n----\n\n" ./docs/documentation/api/api.md

Here the first argument to sed, -i is for in place. Then that strange 1i means that it will insert something before the first line, once. Then we have our header, and finally the file.

Happy hacking!

Subscribe