Jarek Przygódzki. Blog programisty

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

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 , ,

Binarne patche w dystrybucji oprogramowanie i uruchamianie bibliotek Javy w .NET

leave a comment »

Badałem niedawno kwestię wykorzystania binarnych, przyrostowych patchy w dystrybucji oprogramowania. Głownie interesowały mnie dwie kwestie

  • jak to zrobić
  • na jakie oszczędności można liczyć

Podsumowując, bardzo pozytywnie zaskoczył mnie projekt xdelta a negatywnie xdeltaencoder. Na korzyść tego drugiego przemawia tylko fakt, że jest napisany w Javie. Wadą obu projektów jest licencja GPLv2  która uniemożliwia ich wykorzystanie w projektach zamkniętym kodzie. GPLv2  jest  licencją wirusową – każdy program zlinkowany z biblioteką na takiej licencji to tzw.  dzieło pochodne (derived work). 

Pomimo rozczarowania postanowiłem przeprowadzić mały eksperyment i uruchomić tą bibliotekę w środowisku .NET korzystając z IKVM.NET co okazało się… zdumiewająco proste. Wynik jest na GitHubie w repozytorium XDeltaEncoderNet

Co ciekawe, patche wygenerowany przez JVM i .NET zwykle odrobinę się różnią, co może wynikać z różnic w implementacji algorytmów kompresji.

Written by Jarek Przygódzki

Sierpień 19, 2014 at 9:34 pm

Napisane w .NET, Java

Tagged with , ,

Obserwuj

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