Jarek Przygódzki. Blog programisty

Ogólne przemyślenia na temat rzemiosła / sztuki / nauki programowania i tematów pokrewnych.

Windows Slowdown, Investigated and Identified

leave a comment »

Originally posted on Random ASCII:

I recently noticed that my Windows 7 home laptop was running slower than usual. It seemed to be spending a lot of time waiting on disk I/O. When I looked at Task Manager it showed that my laptop was caching about one fifth as much disk data as normal, but the cause of this was not obvious.

Part of my job at Valve is to be a performance expert – to investigate both mundane and esoteric performance problems. So when I realized that I had a serious and systemic problem I knuckled down and brought all the tools of my trade to bear, and ultimately I found the culprit.

View original 2 391 słów więcej

Written by Jarek Przygódzki

Marzec 4, 2015 at 11:30 am

Napisane w Uncategorized

Functoriality

leave a comment »

Originally posted on   Bartosz Milewski's Programming Cafe:

This is part 8 of Categories for Programmers. Previously: Functors. See the Table of Contents.

Now that you know what a functor is, and have seen a few examples, let’s see how we can build larger functors from smaller ones. In particular it’s interesting to see which type constructors (which correspond to mappings between objects in a category) can be extended to functors (which include mappings between morphisms).

Bifunctors

Since functors are morphisms in Cat (the category of categories), a lot of intuitions about morphisms — and functions in particular — apply to functors as well. For instance, just like you can have a function of two arguments, you can have a functor of two arguments, or a bifunctor. On objects, a bifunctor maps every pair of objects, one from category C, and one from category D, to an object in category E. Notice that this is…

View original 4 261 słów więcej

Written by Jarek Przygódzki

Luty 23, 2015 at 8:04 am

Napisane w Uncategorized

WildFly, Vaadin CDI i WebSockety

leave a comment »

WidFly 8 posiada irytujące ograniczenie – wszystkie endpointy WebSocket muszą być wdrożone w trakcie inicjalizacji aplikacji webowej. W konsekwencji w aplikacji wykorzystującej oficjalną integrację frameworka Vaadin z CDI komunikacja pomiędzy częścią kliencką (uruchomioną w przeglądarce) i serwerową zamiast korzystać z WebSocket-ów  downgrade’uje  się do techniki long polling co ma negatywne konsekwencje (głównie wydajnościowe).
vaadin-long-polling

Problem ten i ogólne rozwiązane opisane są tutaj, ale w przypadku wykorzystania plugina integrującego Vaadina z CDI należy postąpić nieco inaczej.  Okazuje się, że wystarczy utworzyć własny servlet dziedziczący po klasie VaadinCDIServlet

import javax.servlet.annotation.WebServlet;

@WebServlet(
        loadOnStartup = 1, 
        urlPatterns = { "/*" }, 
        asyncSupported = true, 
        name = "vaadinCdiServlet")
public class WildFlyVaadinCDIServlet
 extends com.vaadin.cdi.server.VaadinCDIServlet {

}

i problem „magicznie” się rozwiązuje. Dlaczego to rozwiązanie działa?

Written by Jarek Przygódzki

Luty 22, 2015 at 10:26 pm

Napisane w CDI, Vaadin

Tagged with , , , ,

Internal or public?

leave a comment »

Originally posted on Fabulous adventures in coding:

Suppose we have a sealed internal class C with a member M intended to be accessed from throughout the assembly:

internal sealed class C
{
  ??? void M() { ... }
}

Should the accessibility modifier at ??? be internal or public?

View original 415 słów więcej

Written by Jarek Przygódzki

Grudzień 20, 2014 at 9:28 pm

Napisane w Uncategorized

Sortowanie kolekcji z wykorzystaniem wyrażeń lambda w Java 8

leave a comment »

Sortowanie kolekcji obiektów po wybranym atrybucie

Jedną z rzeczy które zawsze irytowały mnie w Javie była ilość kodu która trzeba było napisać żeby posortować kolekcję zawierającą typu zdefiniowane przez użytkownika po kluczu który implementuje już interfejs Comparable. Weźmy prosty obiekt POJO

class Person {

    public Integer   id;
    public String    firstName;
    public String    lastName;
    public LocalDate birthDate;

    public Person(Integer id, String firstName, String lastName, LocalDate birthDate) {
        this.id        = id;
        this.firstName = firstName;
        this.lastName  = lastName;
        this.birthDate = birthDate;
    }

    @Override
    public String toString() {
        return String.format(
                "Person {id=%d, firstName=%s, lastName=%s, birthDate=%s}",
                id, firstName, lastName, birthDate);
    }
}

Jak posortować listę takich obiektów po dacie urodzin? Jednym z popularnych sposobów jest zdefiniowanie komparatora jako klasy anonimowej

	Collections.sort(personList, new Comparator<Person>() {
		@Override
		public int compare(Person p1, Person p2) {
			return p1.birthDate.compareTo(p2.birthDate);
		}
	   });
   }

Kod nie wygląda zbyt elegancko a co więcej nie uwzględnia sytuacji, gdy data zatrudnienia będzie równa null
Można też oczywiście zdefiniować komparator w osobnej klasie, ma to sens gdy takie sortowanie powtarza się w wielu miejscach gdyż umożliwia to ponowne wykorzystanie kodu


class PersonByBirthDateComparator implements Comparator<Person>() {
	@Override
	public int compare(Person p1, Person p2) {
		return p1.birthDate.compareTo(p2.birthDate);
	}
   });
}
Collections.sort(personList, new PersonByBirthDateComparator());

Biblioteka na ratunek?

Skoro sortowanie kolekcji obiektów po wybranym atrybucie jest tak uciążliwe, to na pewno musi istnieć jakaś biblioteka która to usprawnia – lenistwo jest przecież jedną z cnót programistów, prawda?
I rzeczywiście, częściowo tak jest

Google Guava

Korzystając z klasy Ordering możemy problem sortowanie rozwiązać tak

Collections.sort(personList, Ordering.natural().
	onResultOf(new Function<LocalDate, Person>() {
	  public String call(Person p) {
		 return p.birthDate;
	  }))
  .nullsLast();

Znowu nie wygląda to dobrze, ale wyrażenia lambda ratują sytuację

Collections.sort(personList, Ordering.natural().
	onResultOf(p -> p.birthDate).
	nullsLast();

Apache Commons BeanUtils

Innym rozwiązaniem jest wykorzystanie klasy BeanComparator

Collections.sort(personList, new BeanComparator("birthDate"));

Kod wygląda dobrze, ale w praktyce ma dwie poważne wady. Pierwszą z nich jest duży narzuty wydajnościowy wynikający z dostępu do pól klasy przez refleksję. Drugim problem występuje przy automatycznej refaktoryzacji – jeśli ktoś ma tak jak podświadomy nawyk wciskania Alt+Shift+R gdy widzi nazwę która mu się nie podoba może narobić niezłego bałaganu

Czy może być lepiej

W dotychczasowych dywagacji nasuwają się niezbyt optymistyczne wnioski – a jak dotąd poruszyliśmy tylko prostszy wariant problemu. Co w sytuacji, gdy chcemy posortować obiekty po kluczu złożonym (tj. po kilku polach na raz)? Dlaczego sortownie po kluczu który implementuje już interfejs Comparable jest tak niewygodne?

Z przekonania, że może być lepiej narodził się projekt jarek-przygodzki/more-collections. Nie jest to jeszcze w żadnym razie dzieło skończone, co więcej kod obsługujący sortowanie po kluczach złożonych nie jest zbyt elegancki (ale tutaj chyba lepiej być nie może ze względu na ograniczenia typów uogólnionych) – ale efekty i tak są zachęcające

// Sortowanie imieniu
MoreCollections.sort(personList, p -> p.firstName);
// Sortowanie po  dacie urodzenia
MoreCollections.sort(personList, p -> p.birthDate);
// Sortowanie po kluczu złożonym [lastName, firstName], tj. najpierw po nazwisku
// a potem po imieniu
MoreCollections.sort(personList,
    p -> p.lastName,
    p -> p.firstName);

Jak to działa

Rozwiązanie opiera się o obiekty funkcyjne java.util.function.Function<T, R> które służą to wyłuskania z obiektu typu T klucza sortowania typu R gdzie typ R musi spełniać ograniczenie R extends Comparable<? super R>. Następnie na podstawie takiego operatora wyłuskania (lub kilku) budowany jest specjalny komparator i przekazywany to metody Collections.sort

Comparator<T>; comparator = CombinedComparator.build(propertyAccessor);
Collections.sort(list, comparator);

Na resztę rozwiązania składają się klasy CombinedComparator łącząca wiele komparatorów w jeden i CombinedComparator.ByPropertyComparator która sortuje obiekty typu T względem klucza zwracanego przez wskazaną funkcję. Sam kod biblioteki nie korzysta co prawda z funkcjonalności wersji 8, ale wyrażania lambda pozwalają pisać bardzo idiomatyczny kod z niej korzystający.

Written by Jarek Przygódzki

Wrzesień 18, 2014 at 9:39 pm

Napisane w Java

Tagged with , , ,

Java3D w OSGi

leave a comment »

W repozytorium jarek-przygodzki/Java3D-OSGi znajdują się eksperymenty z integracją biblioteki Java3D z OSGi (szczegóły dotyczące poszczególnych rozwiązań są w komentarzach Git). Szczególnie w przypadku wersji 1.6 mamy dużo ciekawych możliwości. Wszystkie mają swoje wady i zalety, ale w przypadku aplikacji opartej o Eclipse RCP najlepszym jest rozwiązanie z pakunkiem częściowym dla każdej kombinacji os/ws/arch i wykorzystanie dyrektywny Eclipse-PlatformFilter w manifeście. Bardzo ładnie komponuje się zarówno z p2 jak i ze środowiskiem deweloperskim.

Written by Jarek Przygódzki

Wrzesień 16, 2014 at 9:41 pm

Napisane w Java

Tagged with , , ,

Vaadin Eclipse Plugin i projekt oparty o Maven – kompilacja motywu

leave a comment »

Od pewnego czasu mam do czynienia z Vaadin Framework ( w kombinacji Vaadin/WildFly/Maven/Eclipse). Integracja przebiegała doskonale z wyjątkiem pewnego drobiazgu – próba kompilacji motywu kończyła się błędem „Select a theme file (.scss) or a Vaadin project to compile.”. W zasadzie nie przeszkadzałoby mi to specjalnie bo w trybie deweloperskiem Vaadin potrafi kompilować pliki SCSS w locie gdyby nie ogromne opóźnienia (rzędu 10s-100s) przy uruchomieniu serwera w trybie Debug (opisane tutaj). Obejściem jest oczywiście ręczna kompilacja SCSS – tyle że ta kończyła się komunikatem „Select a theme file (.scss) or a Vaadin project to compile.”. W swoim czasie zignorowałem ten problem; dodałem do pliku POM nową zależność

    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-themes</artifactId>
        <version>${vaadin.version}</version>
    </dependency>

i w razie potrzeby kompilowałem motyw z linii poleceń

mvn vaadin:compile-theme

W końcu ciekawość wzięła górę i postanowiłem udać się do źródeł (przypadkowa gra słów)… i pojawił się problem. Gdzie one są? Większość projektów Vaadin jest na GH oraz na witrynie dev.vaadin.com/git/ – ale pluginu dla Eclipse tam nie ma. W końcu udało mi się je znaleźć na http://dev.vaadin.com/svn/integration/eclipse/ – ale nie było to bynajmniej pierwsze miejsce w którym szukałem. Tutaj mała dygresja – plugin nie działa w pełni w Eclipse 4.4 (Luna) ze względu na wykorzystanie klasy org.eclipse.mylyn.internal.provisional.commons.ui.AbstractNotificationPopup która w nowej wersji Mylyna zmieniła nazwę na org.eclipse.mylyn.commons.ui.dialogs.AbstractNotificationPopup

Kod odpowiadający za kompilację motywu znajduje się w klasie com.vaadin.integration.eclipse.handlers.CompileThemeHandler a problem tkwił w metodzie compileFile gdzie znajduje się sprawdzenie, czy projekt ma naturę Vaadin

    // com.vaadin.integration.eclipse.VaadinFacetUtils.isVaadinProject(IProject)
    /**
     * Check whether a project has the Vaadin project nature.
     * 
     * @param project
     * @return true if the project is an Vaadin project
     */
    public static boolean isVaadinProject(IProject project) {
        if (project == null) {
            return false;
        }

        try {
            IFacetedProject fproj = ProjectFacetsManager.create(project);
            return fproj != null &amp;&amp; fproj.hasProjectFacet(VAADIN_FACET);
        } catch (CoreException e) {
            ErrorUtil.handleBackgroundException(e);
            return false;
        }
    }

Okazało się, że wystarczy dodać facet Vaadin Plug-in for Eclipse 7.0 w konfiguracji projektu i kompilacja zaczęła działać. Jest to oczywiście rozwiązanie chwilowe – katalog .settings jest wyłączony z kontroli SCM – więc przy następnym pobraniu projektu z repozytorium trzeba będzie to potwórzyć :-< .

Written by Jarek Przygódzki

Wrzesień 16, 2014 at 9:19 pm

Napisane w Java

Tagged with , ,

Obserwuj

Otrzymuj każdy nowy wpis na swoją skrzynkę e-mail.