Tag: Code

Java: Unterschiede zwischen && vs. &

Viele, denke ich, wissen gar nicht, das man eine Verknüpfung auch mit einem einfach & durchführen kann. Was der Unterschied zum doppelten && ist, soll der folgende Artikel beleuchten. Dieses Verhalten ist unabhängig von der Programmiersprache, für PHP habe ich es auch nochmals demonstriert. Im folgenden Beispiel wird Java verwendet. Grundsätzlich müssen bei einer UND-Verknüpfung alle Bedingungen WAHR sein, damit das Statement ausgeführt wird. Sollte nur eine Bedingung FALSE sein, wird der ELSE-Zweig genommen. Der Unterschied zwischen & und && ist jetzt nur, wie geht es weiter, wenn die erste Bedingung bereits FALSE ist.

Beispiel von && vs &

[java]
public class UndUnd {

public static void main(String[] args) {

if(a() && b()){
System.out.println("Fertig");
}else{
System.out.println("UnFertig");
}

}

public static boolean a(){
System.out.print("Hallo ");
return false;
}

public static boolean b(){
System.out.println("Welt");
return true;
}
}

// Ausgabe: Hallo
// Unfertig
[/java]

Bei Verwendung des && Operators, wird sofort nach der ersten fehlerhaften Bedingung abgebrochen. Für die Performance ist dies natürlich optimal. Jedoch könnte es sein, das sich in der Funktion B Programmcode befindet der trotzdem auf jeden Fall ausgeführt werden soll, genauso wie in der Funktion A. Hier würde man den einfach & Operator verwenden.

[java]
public class UndUnd {

public static void main(String[] args) {

if(a() & b()){
System.out.println("Fertig");
}else{
System.out.println("UnFertig");
}

}

public static boolean a(){
System.out.print("Hallo ");
return false;
}

public static boolean b(){
System.out.println("Welt");
return true;
}
}

// Ausgabe: Hallo Welt
// UnFertig
[/java]

Performance && vs. &

Für die Performance sollte man immer && verwenden, weil dann bereits nach der ersten fehlerhaften Bedingung abgebrochen wird. Wenn man gewährleisten will das alle Bedingungen überprüft werden, sollte man dagegen das einfach & wählen.

Zusammenfassung – tl;dr

Soll sichergestellt werden, dass alle Bedingungen in einem if untersucht werden, sollte ein einfaches & verwendet werden, besser für die Performance ist die Verwendung ist &&.

Weitere Fragen zur Java-Programmierung? Jetzt einfach und schnell einen Kommentar hinterlassen, mit E-Mail Adresse, und deine Frage wird ausführlich im BugBlog beantwortet.

[random_content group_id=”210″ num_posts=”1″]

WordPress 2.6.5 is available! Please update now.

Gestern Nachmittag hatte ich bei Securityfocus erst die Anzahl von Vulnerabilities zwischen Typo3 und WordPress verglichen. Typo3 kam auf zwei Seite, WordPress auf drei. Wobei viele Meldungen auf Typo3 Extensions entfallen. WordPress hat diesen Bonus nicht.

Bevor ich jetzt jedoch die ganze Update Prozedur starte, habe ich mir die Unterschiede zwischen WordPress 2.6.3 und WordPress 2.6.5 angeschaut. Die WordPress Version 2.6.4 wurde übersprungen, da es wohl eine Fake Version gab.

Das Update würde insgesamt nur 5 Dateien betreffen. Dafür den Aufwand treiben, die Datenbank zu sichern, alles löschen, das ganze WordPress Paket einspielen, ist mir zu aufwendig. Ich werde es händisch machen und mir dabei gleich mal die Fehler anschauen.

In einer Datei wird bloß die Versionsnummer hochgezählt. Manche Blogs behaupten, das Technorati Blogs aus dem Index schmeißt, die eine ältere WordPressversion verwenden, wie alt diese jedoch sein muß konnte ich bisher nicht herausfinden. Prinzipiell ist dies jedoch für mich ein Schwachstelle, wenn man “von außen” herausfinden kann, auf welcher Version ein System läuft. Dadurch wird es dem Angreifer umso leichter gemacht, den richtigen Hebel auszuwählen um anzusetzen.

Schauen wir uns einen weiteren Fehler an. Dies soll keine Klugscheißerei werden, denn die kann keiner leiden, aber nur aus Fehlern lernt man.

[php]
// File: /wp-admin/users.php

129 129 $go_delete = false;
130 130 foreach ( (array) $userids as $id ) {
131 $id = (int) $id;
131 132 $user = new WP_User($id);
132 133 if ( $id == $current_user->ID ) {
[/php]

Zeile 5 bzw. 131 ist neu. Bevor die Variable $id an WP_User übergeben wird, wird sie nach int gecasted. Dies ist auch sinnvoll, denn ursprünglich kommt das Array direkt aus einem Formular und nicht etwa aus der Datenbank.
Was mir jedoch nicht ganz schlüssig ist, warum wird der Cast nicht direkt in der Methode gemacht? Die Methode wird bestimmt noch an mehreren Stellen aufgerufen und man sollte der Methode die Verantwortung übertragen, sicherzustellen, das nur die richtigen Werte übertragen werden.

Betrachten wir noch eine weitere Lücke, die verdeutlichen soll, warum PHP Anwendungen so anfällig sind. In Programmiersprachen wie Java oder JavaScript wäre der Fehler schon von Anfang an aufgefallen.
Sehen wir uns zuerst den alten Code an:
[php]
// File: /wp-includes/feed.php

498 echo ‘http’
499 . ( $_SERVER[‘https’] == ‘on’ ? ‘s’ : ” ) . ‘://’
500 . $_SERVER[‘HTTP_HOST’]
501 . wp_specialchars(stripslashes($_SERVER[‘REQUEST_URI’]), 1);
[/php]

Und nun die Neue:

[php]
// File: /wp-includes/feed.php

498 $host = @parse_url(get_option(‘home’));
499 $host = $host[‘host’];
500 echo clean_url(
501 ‘http’
502 . ( (isset($_SERVER[‘https’]) && $_SERVER[‘https’] == ‘on’) ? ‘s’ : ” ) . ‘://’
503 . $host
504 . stripslashes($_SERVER[‘REQUEST_URI’])
505 );
[/php]

Bevor jetzt also geprüft ob der $_SERVER[‘https’] == ‘on’ wird erstmal überprüft ob die Variable ob überhaupt gesetzt ist. Wenn die Variable nicht gesetzt ist, macht es auch keinen Sinn zu überprüfen ob sie on ist. Sollte die erste Bedingung bereits fehlschlagen wird sofort abgebrochen. Dafür sorgt das &&.

Java Tutorial: Hibernate, MySQL, Annotations

Heute Morgen das Beispiel mit XML veröffentlicht, folgt jetzt das gleiche Beispiel mit Annotations. Diese sind erst seit Java 5 verfügbar und bieten den Vorteil man muss nicht immer zwei Dateien anpassen. Mit Annotations ist es möglich direkt im Java Code festzulegen wie das Objekt später in der Datenbank abgelegt wird.

Bereits in der Übersicht kann man sehen, das die Konfigurationsdatei für das Objekt wegfällt. Die Konfiguration die vorher in der der XML Datei vorgenommen wurde wird jetzt direkt in die Java Klasse implementiert. Natürlich entfällt dann auch die Angabe über die Konfigurationsdatei in der Hibernate Konfiguration.
Aber genug Geschwätz sehen wir uns das Objekt an:

[java]
// File: Tisch.java

package obj;

import java.io.Serializable;
import java.text.MessageFormat;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

@Entity
public class Tisch implements Serializable{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@SequenceGenerator(name = “tisch_gen”, sequenceName = “tisch_id_seq”)
private Integer id;
private Integer Fuesse;
private String Material;

public Tisch(){ }

private Integer getId() {
return id;
}

private void setId(Integer id) {
this.id = id;
}

public Integer getFuesse() {
return Fuesse;
}

public void setFuesse(Integer fuesse) {
Fuesse = fuesse;
}

public String getMaterial() {
return Material;
}

public void setMaterial(String material) {
this.Material = material;
}

public String toString() {
return MessageFormat.format(“{0}: Fuesse={1}, Material={2}”, new Object[] {
getClass().getSimpleName(), Fuesse, Material });
}
}
[/java]

Wie oben bereits oft erwähnt entfällt die Konfigurationsdatei. Also kommen wir gleich zu der Session.

[java]
// File: SingSessionFactory.java

package hibe;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

public class SingSessionFactory {

/** The single instance of hibernate SessionFactory */
private static org.hibernate.SessionFactory sessionFactory;

/**
* Default constructor. It is private to guaranty singleton
*/
private SingSessionFactory() {
}

static {
final AnnotationConfiguration cfg = new AnnotationConfiguration();
cfg.configure(“/hibernate.cfg.xml”);
sessionFactory = cfg.buildSessionFactory();
}
public static SessionFactory getInstance() {
return sessionFactory;
}

}
[/java]

Die Main Klasse

[java]
// File: HibeMySQL.java

package exa;

import hibe.SingSessionFactory;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;

import obj.Tisch;

public class HibeMySQL {

private static Logger log = Logger.getLogger(HibeMySQL.class);

public static void main(String[] args) {
Tisch wohnzimmer = new Tisch();
wohnzimmer.setMaterial(“Eiche”);
wohnzimmer.setFuesse(3);

Session ses = SingSessionFactory.getInstance().getCurrentSession();
Transaction tx = ses.beginTransaction();

ses.save(wohnzimmer);

tx.commit();
}
}
[/java]

Die angepasste Konfiguration von Hibernate

[xml]



jdbc:mysql://localhost:3306/bank root com.mysql.jdbc.Driver org.hibernate.dialect.MySQLDialect org.hibernate.transaction.JDBCTransactionFactory thread true

true update


[/xml]

Zur Vollständigkeit noch die Konfigurationsdatei von Log4J.

[xml]
# File: log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L – %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L – %m%n

### set log levels – for more verbose logging change ‘info’ to ‘debug’ ###

log4j.rootLogger=debug, stdout

log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=info

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
log4j.logger.org.hibernate.cache=info

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
[/xml]

Java Tutorial: Hibernate, MySQL, XML

Hibernate Struktur Mit Hibernate ist es möglich, Objekte direkt in der Datenbank abzulegen. Dieses Beispiel soll einfach mal ein funktionierendes Beispiel beschreiben ohne dabei zu sehr in die Tiefe zu gehen. Für die Tiefe gibt es später eine Reihe weiterer guter Webseiten und Bücher.

Systemvoraussetzungen: MySQL Datenbank, Java 5 oder höher, Entwicklungsumgebung mit XML und Java Support, JDBC MySQL Treiber, Hibernate Core, Hibernate Annotations sollte man alles bei der Suchmaschine seines Vertrauens finden können.

Bei den Bezeichnungen der einzelnen Dateien orientiere ich mich an der obigen Grafik. Um uns späteren Ärgern zu ersparen sollte man zuerst die ganzen JARs in sein Projekt einbinden. Normalerweise sollte man immer so wenig einbinden aber da uns die Performance im Moment egal ist und wir erstmal nur sehen wollen wie es funktioniert, binden wir wahllos alles ein.

Als nächstes brauchen wir ein Objekt, den Tisch.

[java]
// File: Tisch.java

package obj;

import java.io.Serializable;
import java.text.MessageFormat;

public class Tisch implements Serializable{

private static final long serialVersionUID = 1L;

private Integer id;
private Integer Fuesse;
private String Material;
private Tisch tisch;

public Tisch(){}

private Integer getId() {return id;}

private void setId(Integer id) {this.id = id;}

public Integer getFuesse() {return Fuesse;}

public void setFuesse(Integer fuesse) {Fuesse = fuesse;}

public String getMaterial() {return Material;}

public void setMaterial(String material) {this.Material = material;}

private Tisch getTisch() {return tisch;}

private void setTisch(Tisch tisch) {this.tisch = tisch;}

public String toString() {
return MessageFormat.format(“{0}: Fuesse={1}, Material={2}”, new Object[] {
getClass().getSimpleName(), Fuesse, Material });
}
}
[/java]

Aus Gründen der Übersichtlichkeit habe ich den Code hier etwas zusammengefasst. Anschließend müssen wir mittels XML sagen wie der Tisch in unserer Datenbank gemapped werden soll.

[xml]









[/xml]

Damit später nur eine Verbindung zur Datenbank vorhanden ist muss man die Session als Singleton implementieren.

[java]
// File: SingSessionFactory.java

package hibe;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class SingSessionFactory {

private static org.hibernate.SessionFactory sessionFactory;

private SingSessionFactory() {}
static {

final Configuration cfg = new Configuration();
cfg.configure(“/hibernate.cfg.xml”);
cfg.buildSessionFactory();
sessionFactory = cfg.buildSessionFactory();
}

public static SessionFactory getInstance() {
return sessionFactory;
}
}
[/java]

Anschließend können wir unsere Main implementieren.

[java]
// File: HibeMySQL.java

package exa;

import hibe.SingSessionFactory;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;

import obj.Tisch;

public class HibeMySQL {

private static Logger log = Logger.getLogger(HibeMySQL.class);

public static void main(String[] args) {
Tisch wohnzimmer = new Tisch();
wohnzimmer.setMaterial(“Eiche”);
wohnzimmer.setFuesse(3);

Session ses = SingSessionFactory.getInstance().getCurrentSession();
Transaction tx = ses.beginTransaction();

ses.save(wohnzimmer);

tx.commit();
}
}
[/java]

Am Schluss brauchen wir noch zwei Konfigurationsdateien. Die erste für Hibernate und der MySQL Verbindung.

[xml]




jdbc:mysql://localhost:3306/bank root com.mysql.jdbc.Driver org.hibernate.dialect.MySQLDialect org.hibernate.transaction.JDBCTransactionFactory thread true

true update

[/xml]

Als letztens brauchen wir noch eine Konfiguration für Log4j damit wir eine schöne Ausgabe erhalten was die Datenbank so treibt.

[xml]
# File: log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L – %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L – %m%n

### set log levels – for more verbose logging change ‘info’ to ‘debug’ ###

log4j.rootLogger=debug, stdout

log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=info

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
log4j.logger.org.hibernate.cache=info

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
[/xml]

Die Konfigurationseinstellungen sind zum größten Teil aus anderen Beispielen entliehen. Es geht hier prinzipiell nur darum mal ein ein einfaches Beispiel zu zeigen.