2013-12-15

Loopia + Gmail = problem!

Vi reggade ett domännamn och webhotell på loopia.se för få en egen mail-adress. Den mail-adressen var tänkt att användas för att programmatiskt skicka ut mail till användarna från servern.
När vi provkörde detta visade det sig att mailen aldrig kom fram till @gmail.com-adresser. Anledningen är att folk har missbrukat loopia-mailen till att skicka ut spam. Som resultat av det har dom större företagen (Google bla) blockat alla inkommande mail ifrån loopia vilket gör att mailen inte kommer fram alls.

Slutsats. Använd dig INTE av loopia om du söker en tjänst för att regga en egen mail-adress att skicka mail ifrån. Vill bara upplysa er om detta då det säkert är någon mer där ute som någon gång kommer behöva välja ett företag att regga domän hos.

Lösningen på detta vet jag inte än. Loopia vägrar betala tillbaka pengarna.
Postar här om jag hittar en "work around" på problemet.

2013-12-13

NullPointerException vid login


*Moderator*'
Håll inläggen korta och relevanta.

Om ni har två tabeller i ett schema som har beroenden till varandra, se då till att rensa båda då det annars  finns risk för ett NullPointerException.
Detta är bara förslag på förändring. Du får själv redigera det. Men håll det kort och informationsrikt det skall gå fort att förstå problemet och lösningen.


*Slut*


Vi hade en gästbok med en login funktion. Till gästboken fanns det användare och meddelanden som sparades i en databas. Varje användare hade ett username och ett id och varje meddelande hade en text och ett id kopplat till användaren. Plötsligt efter att ha hashat och saltat lösenorden i databasen  så fick jag ett nullPointerException.

Felet låg i att jag hade rensat bort allt gammalt i min users tabell i databasen eftersom det såg fult ut med både hashade lösenord och icke hashade lösenord. Men jag hade inte rensat i meddelandetabellen vilket gjorde att där fanns meddelanden från userId 3 och 4 medans jag i min users tabell hade bara två stycken användare sparade. Detta skapade mitt nullPoiterException.
Så vi kan lära oss av detta att om vi har flera tabeller med kolumner som hör ihop glöm inte att rensa den datan också annars kommer ett exception att kastas. 

2013-12-11

Missing artifact jdk.tools:jdk.tools:jar:1.6 /Maven

Detta felmeddelande uppstod när ett nytt dependecy lades till i föräldrapomen.
Dependecyt i detta faller var Solr-core.

Lösning: Problemet grundar sig i att Maven versionerna till Linux och Windows inte kompileras med java tools till skillnad från Mac. En lösning för problemet är att helt enkelt lägga in ett dependency för detta i sin parent pom. Denna lösningen fungerar dock bara om man håller sig till en plattform. Alltså utvecklar man på olika plattformar så kommer det att sluta fungera på Mac.
Lösning på detta kommer komma inom kort.

Java tools dependency

<dependency>
  <groupId>com.sun</groupId>
  <artifactId>tools</artifactId>
  <scope>system</scope>
  <systemPath>${java.home}/lib/tools.jar</systemPath>
</dependency>

Lösning 2:

Som nämnt tidigare så ligger problemet i att tools.jar inte följer med trotts att den finns som standard i samtliga JDK utgåvor som finns att få tag på.

Efter tips från ett pro(Bertil) så fick vi reda på att vi skulle försöka undvika att det kompileras olika beroende på vilket system man sitter på. Detta är något man kan lösa genom att bygga olika profiler beroende på vilket OS man sitter på (men detta är alltså inte att rekommendera).

Det man måste göra är att peka på rätt VM (Virtual machine)
Ett sätt att göra detta på är att ändra i sin IDE. I detta fallet är det Eclipse.

I mappen där man packat upp Eclipse finns det en fil som heter eclipse.ini, man får redigera den till att se ut så här (Självklart med sin egen path till sin JDK) Det viktiga i texten nedan är markerat.

-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.200.v20130521-0416
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vm
/usr/lib/jvm/jdk1.7.0_25/bin/java
-vmargs
-Dosgi.requiredJavaVersion=1.6
-XX:MaxPermSize=256m
-Xms40m
-Xmx512m



Vill tacka Bertil för hjälp och tips angående detta problem.

OutOfMemoryError

Det verkar som att alla vägar bär till Rom i frågan om hur man löser OutOfMemoryError  - Java heap Space. Vissa krångligare än andra men detta löste i alla fall mitt problem och är väldigt enkelt.

JVM behöver mer RAM för att kunna köras och det kan ställas in i eclipse.

1. Windows ->preferences (mac: eclipse -> preferences)
2. Java - Installed JREs
3. Välj JRE och klicka på Edit
4. Vid default VM argument fältet skriv in -Xmx1024M. (Eller mindre än 1024)
5. Tryck på finish.

DONE!

2013-12-10

Easymock tutorial

I skolan har vi använt oss en del av något som kallas Easymock och det tog mig ett tag att förstå mig på hur det fungerar. 
Easymock är ett sätt att testa en viss del av koden som har beroenden till andra delar. Easymockning fungerar som en bandspelare:  man spelar in något och man spelar upp något.


I vårt exempel så har vi endast en service som är beroende av ett repository. Vi struntar i databasen, men jag har ändå med den på bilden för att få lite mer förståelse.
Nu har vi metoder i våran service som vi vill testa att de fungerar, men servicen har ett beroende till vårat repository och vi vill enbart testa services. Detta löser vi genom att mocka bort vårt repository.

Först vill jag visa bara hur metoden ser ut som vi skall testa. 

@Service
public class PersonServiceImpl implements PersonService {

 @Autowired
 private PersonRepository personRepository;

 public Person createPerson(Person person) {
  
  long id = personRepository.createPerson(person); 
  return personRepository.getPerson(id);
 }

Som du ser har vi ett anrop till vårat repository där logiken ligger för att kunna skapa vår person. Detta beroendet måste vi mocka bort.

Vad man gör med Eaymock är att man först spelar in ett scenario med mockning och sedan spelar man upp det.

Låt oss titta på detta. 

public class PersonServiceTest {
 
 @Test
 public void testCreatePerson() {
  
  PersonRepository repo = EasyMock.createMock(PersonRepository.class);
  Person person = new Person("Arne", "Anka", "arne@anka.com", "07605050", "");
  EasyMock.expect(repo.createPerson(person)).andReturn(1l);
  EasyMock.expect(repo.getPerson(1l)).andReturn(person);
  EasyMock.replay(repo);
  
  PersonServiceImpl service = new PersonServiceImpl();
  service.setPersonRepository(repo);
  Person newPerson = service.createPerson(person);
  
  assertEquals("Created Person", person, newPerson);
    
 }
Det första som sker är att vi skapar själva mocken som vi vill göra oss oberoende av. Detta görs genom följande kod : EasyMock.createMock(PersonRepository.class);
Efter vi har gjort det så spelar vi in vårt scenario vi fejkar alltså vårt repo.
Eftersom vi skall skapa en Person så börjar vi med att skapa en person och skickar in värden.
När vi skapat en person vill vi använda vår createPerson metod i repot som vi mockar.
EasyMock.expect(repo.createPerson(person)).andReturn(1l);

expect innebär att det är en metod med ett retur värde och vi skickar in vårt egna värde, kan vara precis vad som helst men det måste vara samma datatyp som finns i metoden. I detta fall är det värde 1 som vi väljer av typen long. .andReturn(1l) behövs eftersom metoden vi testar returnerar ett värde. Så vi returnerar samma värde som vi skickade in.
Om du inte har en retur metod behöver du inte skriva expect och inte andReturn efteråt utan du skriver bara repo.cretePerson();
Efter vi har fejkat alla anrop vi behöver så spelar vi in hela scenariot genom att skriva :  EasyMock.replay(repo).
Nu vill vi spela upp alltihopa och testa vår Service.

                PersonServiceImpl service = new PersonServiceImpl();
  service.setPersonRepository(repo);
  Person newPerson = service.createPerson(person);

Vi skapar en referens till vår service och sätter repot som vår service.
Efter det så skapar vi vår person som är det vi har velat testa hela tiden.
Slutligen kör vi själva testet

assertEquals("Created Person", person, newPerson);



2013-12-09

Generera nytt Hello-world Maven-projekt med Maven archetypes

Följande länk beskriver hur man gör:
https://github.com/akquinet/android-archetypes

Ett exempel följer här:

Öppna ett kommando-fönster och ställ dig i den mapp du vill generera Android-projektet i, samt skriv:
mvn archetype:generate -DarchetypeArtifactId=android-quickstart -DarchetypeGroupId=de.akquinet.android.archetypes -DarchetypeVersion=1.0.10 -DgroupId=se.foretag -DartifactId=android-exempel-program -Dplatform=10 -Dpackage=se.foretag.android.exempelpaket

Detta genererar ett helt nytt färskt komplett Hello-world Maven-projekt med pom-filer och allt (med API-level 10) som du kan importera till din IDE. Jättebra, nu kan man t ex hantera dependencies lätt i pom:en istället för att importera jar-filer.

2013-12-08

Bitwise/Bit Shift operatorer och bitar

Detta är mina anteckningar från första veckan i Säker mjukvara kursen. Ni från klassen får gärna redigera denna post om ni vill lägga till något eller korrigera eventuella fel.

I Java används signed bytes som standard. Signed byte kan ha värde mellan -128 till +127
Unsigned bytes kan inte vara ett negativt värde. Värdet på en unsigned byte kan vara 0 till 255

En byte är 8 bitar. Alltså 8 ettor/nollor, dessa ettor och nollor kallas Binärtal
01010101 = 1 byte

Räkna decimaltal, binärtal, hexadecimal:

























En Hexadecimal siffra/bokstav motsvara 4 bits (1 nibble).
Hex F = 1111 Binärt.
Om man har två tecken i ett hexadecimal tal är det 8 bitar.
Hex FF = 11111111 Binärt.
Hex F0 = 11110000 Binärt.

För att tilldela binära värden till en byte i Java kan man skriva så här.
byte b = (byte) 0b100001;
Variabel b har nu värdet 33.

För att tilldela hexadecimala värden till en byte.
byte b = (byte) 0x4A;
Variabel b har nu värdet 74

Bitwise operatorer i Java

NOT = ~
  • Flippar bitarna så alla ettor blir nollor och vise versa.
  • ~1010 = 0101
AND = &
  • Jämför två binära tal. Om en 1a finns i båda talen på samma position blir resultatet 1 på den platsen.
  • 1101 & 0111 = 0101
OR = |
  • Jämför två binära tal. Om endast en 1a finns i något av talen blir resultatet 1 på den platsen.
  • 0101 | 1100 = 1101
XOR = ^
  • Samma som OR men om talet är lika på båda blir resultatet 0.
  • 0101 ^ 1100 = 1001
Bit Shift operatorer i Java

Bit Shift left = << 
  • Flyttar bitarna till vänster. Man anger hur många steg med en siffra efter operatorerna << 2
  • 0110 << 1 = 1100
  • Den nya biten/bitarna som kommer in från vänster sida har alltid värdet 0.
Unsigned Bit Shift right = >>>

  • Samma som bit shift left men åt höger
  • 1100 0000 >>> 2 = 0011 0000
  • Den nya biten/bitarna som kommer in från vänster sida har alltid värdet 0.

Signed Bit Shift right (används nästan aldrig i praktiken) = >>
  • Samma som Bit Shift left men behåller teckenbiten (MSB biten längst till vänster). 
  • 1110 0000 >> 2 = 1111 1000
  • 0110 0000 >> 2 = 0001 1000

public static void main(String args[]) {

int a = 0b0110;  // 6
int b = 0xE; //14, 1110

System.out.println("~a : " + (~a));

System.out.println("a & b : " + (a & b));

System.out.println("a | b : " + (a | b));

System.out.println("a ^ b : " + (a ^ b));

System.out.println("a << b : " + (a << b));

System.out.println("a >> 2 : " + (a >> 2));

}

Resultat:
~a : -7
a & b : 6
a | b : 14
a ^ b : 8
a << b : 98304
a >> 2 : 1



2013-12-06

Bootstrap modals renderas fel på iOS när det virtuella tangentbordet visas

I mobil versionen av Safari finns en bugg som gör att en Bootstrap modal med ett input fält renderas fel när det virtuella tangentbordet visas. Tangentbordet skjuter upp/ner den mörka bakgrunden och visar innehållet som ligger bakom modal:en. Se ett exempel här: https://github.com/twbs/bootstrap/issues/9023

Bootstrap tänker inte fixa detta då detta är en bugg i mobileSafari. Så tills Safari har uppdaterats kan man göra som den här killen: http://www.abeautifulsite.net/blog/2013/11/bootstrap-3-modals-and-the-ios-virtual-keyboard/

I js fil:
// iOS check...ugly but necessary
if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {

    $('.modal').on('show.bs.modal', function() {

        // Position modal absolute and bump it down to the scrollPosition
        $(this)
            .css({
                position: 'absolute',
                marginTop: $(window).scrollTop() + 'px',
                bottom: 'auto'
            });

        // Position backdrop absolute and make it span the entire page
        //
        // Also dirty, but we need to tap into the backdrop after Boostrap 
        // positions it but before transitions finish.
        //
        setTimeout( function() {
            $('.modal-backdrop').css({
                position: 'absolute', 
                top: 0, 
                left: 0,
                width: '100%',
                height: Math.max(
                    document.body.scrollHeight, document.documentElement.scrollHeight,
                    document.body.offsetHeight, document.documentElement.offsetHeight,
                    document.body.clientHeight, document.documentElement.clientHeight
                ) + 'px'
            });
        }, 0);

    });

}
Exemplet använder JQuery.

2013-12-05

Final - nyckelordet i Java som många undviker

Nyligen har jag börjat inse hur kod kan optimeras genom att deklarera variabler, metoder och klasser som final och tänkte dela med mig av detta till alla dem som är tillräckligt ninja för att läsa och förstå denna blogg.

Final används oftast i kombination med static för att deklarera konstanter som återanvänds ofta i ens kod, mest frekvent String eller Integer, men givetvis finns det ett större användningsområde än så. För resten av inlägget kommer jag att kalla variabler som deklarerats som final för konstanter.

En konstant måste initieras när den deklareras eller i samtliga konstruktorer, inte ens en setter duger för initiering. Om dessa kriterier inte uppfylls kommer din IDE att ge dig ett kompileringsfel och föreslå att du ta bort final som modifier. Använd final när du vill att en variabel ej skall gå att ändra från det att objektet har instansierats. Ett exempel på detta vore den typiska variabel 'private long id', som man ej brukar ändra men ändå låter förbli en variabel istället för en konstant. En annan fördel med konstanter är att de är trådsäkra och sparar dig från besväret att behöva synkronisera variabler mellan trådar, något som få seniora utvecklare bemestrar.

Har du en klass i din kod som du vet aldrig kommer ärvas vore det smart att deklarera den som final. Konstanta klasser kan ej ärvas och final kan därför inte heller kombineras med abstract. Deklareras en klass som final kommer även alla metoder per automatik bli final.

Väljer du att låta din klass vara "ärvbar" men har metoder i din klass som du inte vill skall kunna overrideas i ärvande klasser så kan du deklarera dem som final.

Men varför skall man göra detta och vad har det för fördelar? Jo, som sagt gör det dina variabler trådsäkra men också att när JVM märker att en klass, metod eller variabel är deklarerad som final kommer den att lägga dem i cache, vilket gör åtkomsten till dem betydligt snabbare, så voíla! Nej, det gör inte någon jättestor skillnad i mindre applikationer, men i stora enterprise applikationer, som kontinuerligt processerar ofattbara mängder data så spelar dessa mikrosekunder en rätt stor roll.

Källa: Functional Programming for Java Developers, av Dean Wampler.

Install maven for Windows

1. Download Maven at http://maven.apache.org/download.cgi

2. Unzip it at location of your choice.

3. Set the JAVA_HOME variable
Make sure your JAVA_HOME variable is set.
Do this at:
Control Panel --> System and Security --> System --> Advanced system settings --> Envirnoment Variables
variable name : JAVA_HOME
variable value : C:\Program Files\Java\jdk1.7.0_45

4. Set the MAVEN_HOME variable
Do this at same loacation as your java_home.
variable name : MAVAN_HOME
variable value : C:\Programmering\apache-maven-3.1.1(NONONO not this filepath... your own filepath!!!)

5. set your path
variable name : PATH
variable value : %MAVEN_HOME%\bin;C:\Programmering\apache-maven-3.1.1\bin
save...


6 Run mvn -version in CMD.

J2EE Preview Server och dynamic web project

Problem:
När jag skulle skapa ett Dynamic Web Project i Eclipse och köra på J2EE Preview server ville inte servleten köra. HTML-sidorna visades men java-koden kördes inte.

Lösning:
Ladda ner ett nytt Eclipse och skapa ett nytt Dynamic Web Project. Det fungerade INTE när jag importerade mitt gamla DWP utan krävdes att jag skapade ett helt nytt. Oklart varför.