analytically :: Mathias Bogaert

Feb 07 2012

Instantiate a class without default constructor

If a Java class does not have a default constructor, it cannot be instantiated. Easy solution (using Google Guava 11 to speed things up):


private final Cache constructorCache = CacheBuilder.newBuilder()
        .build(new CacheLoader() {
            final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
            @Override
            public Constructor load(Class type) throws Exception {
                return reflectionFactory.newConstructorForSerialization(type, Object.class.getDeclaredConstructor(new Class[0]));
            }
        });


public Object newInstance(Class type) throws Exception {
    Constructor customConstructor;
    try {
        customConstructor = constructorCache.get(type);
    } catch (ExecutionException e) {
        throw Throwables.propagate(e.getCause());
    }
    return customConstructor.newInstance(new Object[0]);
}
Enjoy!

+

Morphia LocalDateTimeConverter

When working with Morphia and Joda-Time, it’s handy to directly use Joda-Time’s LocalDateTime instead of Java’s Date. Here is the Morphia converter:


import com.google.code.morphia.converters.SimpleValueConverter;
import com.google.code.morphia.converters.TypeConverter;
import com.google.code.morphia.mapping.MappedField;
import com.google.code.morphia.mapping.MappingException;
import org.joda.time.LocalDateTime;

import java.util.Date;

public final class LocalDateTimeConverter extends TypeConverter implements SimpleValueConverter {
    public LocalDateTimeConverter() {
        super(LocalDateTime.class);
    }

    @Override
    public final Object encode(Object value, MappedField optionalExtraInfo) throws MappingException {
        if (value == null) {
            return null;
        }

        if (!(value instanceof LocalDateTime)) {
            throw new MappingException("Unable to convert " + value.getClass().getName());
        }

        return ((LocalDateTime) value).toDate();
    }

    @Override
    public LocalDateTime decode(Class targetClass, Object fromDBObject, MappedField optionalExtraInfo) throws MappingException {
        if (fromDBObject == null) {
            return null;
        }

        if (fromDBObject instanceof Number) {
            return LocalDateTime.fromDateFields(new Date(((Number) fromDBObject).longValue()));
        }

        if (fromDBObject instanceof Date) {
            return LocalDateTime.fromDateFields((Date) fromDBObject);
        }

        throw new MappingException("Unable to convert " + fromDBObject.getClass().getName());
    }
}
Use it by declaring it like this:

@Converters(LocalDateTimeConverter.class)
public abstract class Model {
    ....

    @Property("lm") // optional
    public LocalDateTime lastModifiedAt;

    ....
} 

Sep 30 2010

Mycila JMX and Guice 2

Getting operational insight into Java applications is quite hard without JMX. Mycila JMX helps you to expose your application’s internals via @JmxBean, @JmxMethod and and @JmxField annotations. Since I’m using Guice for DI, here is an example: First, register your objects:

final JmxExporter jmxExporter = new MycilaJmxExporter(mbeanServer);
bindListener(new AnnotatedElementToTypeLiteralMatcherAdapter(Matchers.annotatedWith(JmxBean.class)), new TypeListener() {
    public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
        typeEncounter.register(new InjectionListener<I>() {
            public void afterInjection(I i) {
                jmxExporter.register(i);
            }
        });
    }
});
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;

import java.lang.reflect.AnnotatedElement;

public class AnnotatedElementToTypeLiteralMatcherAdapter extends AbstractMatcher<TypeLiteral> {
    private final Matcher<AnnotatedElement> classMatcher;

    public AnnotatedElementToTypeLiteralMatcherAdapter(Matcher<AnnotatedElement> classMatcher) {
        this.classMatcher = classMatcher;
    }

    public boolean matches(TypeLiteral typeLiteral) {
        return classMatcher.matches(typeLiteral.getRawType());
    }
}
Then you can use @JmxBean, @JmxMethod and @JmxField. For example:
@JmxField(description = "Handled response XML's (consumed from queue and written to disk)")
@JmxMetric(unit = "response XMLs", type = MetricType.COUNTER)
public AtomicInteger handledResponsesCount = new AtomicInteger(0);

+

Blogging

Hi there! Welcome to my (new) blog. For the first time in about 8 years, I’ve decided to start blogging again. Topics will include entrepreneurship, life, and technology - software development.

Page 1 of 1