Difference between revisions of "Java"

From Sinfronteras
Jump to: navigation, search
(Connecting to a MySQL database using Java)
(Threads)
Line 168: Line 168:
  
 
There is very little content that is needed to make the Jar file run. Inside of this file, you can see that the Main-Class attribute is set to the name of the class file that we want to run when the Jar is double clicked. In the case of this project, the class file that we want to run is called '''Main.class''', so the title Main is used as the value for this attribute. If your class was called MyProgram.class, this would be set to MyProgram.
 
There is very little content that is needed to make the Jar file run. Inside of this file, you can see that the Main-Class attribute is set to the name of the class file that we want to run when the Jar is double clicked. In the case of this project, the class file that we want to run is called '''Main.class''', so the title Main is used as the value for this attribute. If your class was called MyProgram.class, this would be set to MyProgram.
 
==Threads==
 
La siguiente es la referencia colocada por el Prof. para este tema: https://docs.oracle.com/javase/tutorial/essential/concurrency/
 
 
Threads are used to allow our program to do more than one thing at any one time.
 
 
We picture a process which has two tasks that aren't necessarily dependent on each other. They can occur at the same time, each handled by a "thread"
 
 
<div style="text-align: center;">
 
<ul>
 
<li style="display: inline-block;">
 
[[File:Thread.jpg | x280px | thumb | center |]]
 
</li>
 
<li style="display: inline-block;">
 
[[File:Java_thread.png |x280px | thumb | center |]]
 
</li>
 
</ul>
 
</div>
 
 
So, a process (think program) can contain a number of different threads. As the program is running, the processor switches between each of the threads allowing each of them to have some CPU time to run.
 
 
For dual (or more) core machines, each thread can be executed on a separate core, so no switching is neceessary. The threads truly run concurrently.
 
 
In the previous picture you can also see that Thread number 2 has died off and thread 1 continued on. This is ok.
 
 
Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.
 
 
Threads exist within a process — every process has at least one. Threads share the process's resources, including memory and open files.
 
 
Every application has at least one thread — or several, if you count "system" threads that do things like memory management and signal handling. From the programmer’s point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads
 
 
===The difficulty with threads===
 
* Threads can be difficult to work with because their behavior can be unpredictable.
 
* The order in which they are running may change unless synchronized.
 
 
===Some methods available in the Thread class===
 
 
<syntaxhighlight lang="java">
 
// Changes the name of this thread to be equal to the argument name.
 
setName(String name)
 
 
// Changes the priority of this thread. Valid values are 1 through 10.
 
setPriority(int newPriority)
 
 
// Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds
 
sleep(long millis)
 
 
// Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
 
start()
 
 
// Causes the current thread to block (pause) until the specified thread terminates.
 
Thread.join()
 
 
// Causes the current thread to block until the specified thread terminates or the specified number of milliseconds passes
 
Thread.join(long millis)
 
</syntaxhighlight>
 
 
===Creating Threads===
 
We'll see that (just like everything in Java) a thread is just an object. We can create them, use them, etc...
 
 
When we want to create threads, two options are available to us:
 
* Extend the '''thread class''', or
 
* We can implement the '''Runnable''' interface
 
 
 
'''Extend the ''thread class'':'''
 
 
By doing like this we have access to all the methods in the thread class.
 
 
We need to extend the '''thread class''' and add a '''run method''' <span style="background:#00FF00">(Instead of a main method, threads run the '''run()''' method)</span>:
 
 
MyThread.java:
 
<syntaxhighlight lang="java">
 
public class MyThread extends Thread {
 
 
public void run(){
 
// This is the code that is executed when the thread is started
 
// Este es s'olo un c'odigo ejemplo. Aqu'i podr'ia haber cualquier c'odigo
 
for (int i=0 ; i < 100000000 ; i++){
 
System.out.println(this.getName() + ": " + i);
 
 
}
 
 
}
 
 
}
 
</syntaxhighlight>
 
 
Then, when we want to use our thread (in our standard class: MyProgram.java in our example), we create an instance of the thread, then start it.
 
 
<syntaxhighlight lang="java">
 
MyThread t = new MyThread();
 
t.start();
 
</syntaxhighlight>
 
 
 
'''Implement the ''Runnable'' interface:'''
 
 
To do this we just start by making a regular class, but implement the runnable interface.
 
 
After this, we need to add a '''run()''' method to the class (<span style="background:#00FF00">Instead of a main method, threads run the '''run()''' method</span>):
 
 
MyRunnable.java
 
<syntaxhighlight lang="java">
 
public class MyRunnable implements Runnable {
 
 
public void run(){
 
 
for (int i=0 ; i < 100000000 ; i++){
 
System.out.println("My Tread implementing the Runnable interface: " + i);
 
 
}
 
 
}
 
 
}
 
</syntaxhighlight>
 
 
 
'''Then, in our standard class (MyProgram.java in our example)''', when we want to use our thread, we just need to create an instance of the thread ''in case we extended the thread class'' (as we said above), then start it. However, '''if we implemented the Runnable interface''':
 
* We need to create an instance of the  ''Runnable Tread'' we created:
 
<syntaxhighlight lang="java">
 
MyRunnable r = new MyRunnable();
 
</syntaxhighlight>
 
 
* After this, we need to create a ''Thread'' object and pass the ''Runnable Tread'' object we created to it, and then start it:
 
<syntaxhighlight lang="java">
 
Thread tr = new Thread(r);
 
tr.start();
 
</syntaxhighlight>
 
 
 
Whatever code is inside the '''run method''' will be executed when the thread is started.
 
 
For instance, if we would like the thread to sleep for a certain amount of time, we can call:
 
<syntaxhighlight lang="java">
 
try{
 
    myThread.sleep(10000);
 
}catch (InterruptedException e){
 
    e.printStackTrace();
 
}
 
</syntaxhighlight>
 
 
 
A continuación («MyProgram.java») es la «standad class» en donde vamos a utilizar las «Threads» («MyThread.java» and «MyRunnable.java») creadas arriba:
 
 
MyProgram.java:
 
<syntaxhighlight lang="java">
 
import javax.swing.JFrame;
 
 
public class MyProgram extends JFrame{
 
 
public MyProgram(){
 
 
setSize(500,500);
 
setVisible(true);
 
 
// Object created extending the thread class:
 
MyThread t = new MyThread();
 
t.setName("t1");
 
t.setPriority(10);
 
t.start();
 
 
// Object created implementing the runnable interface:
 
MyRunnable r = new MyRunnable();
 
Thread tr = new Thread(r);
 
tr.start();
 
 
}
 
public static void main(String[] args) {
 
new MyProgram();
 
}
 
 
}
 
</syntaxhighlight>
 
 
En el ejemplo anterior hemos creado un JFrame que cuando se abre se ejecuta también el Thread.
 
 
Cuando se ejecuta ''MyProgram.java'' se debe notar que la ejecución no sigue el orden del código. Es decir, en nuestro ejemplo nuestras ''Threads'' sólo imprimen un valores en pantalla. Note que no necesariamente se debe terminar la impresión de todos los valores de la primera ''Thread'' en el código antes de comenzar la segunda. Esta característica impredecible de las Threads fue mencionada en [[Java#The difficulty with threads|The difficulty with threads]]
 
 
A continuación se muestra un ejemplo un poquito más elaborado en el cual la ''Thread'' se ejecuta una vez que se hace clic en un botón desplegado en el ''JFrame''. Para esto se implementa el ''ActionListener''
 
 
GUIThread.java:
 
<syntaxhighlight lang="java">
 
import java.awt.event.ActionEvent;
 
import java.awt.event.ActionListener;
 
 
import javax.swing.JButton;
 
import javax.swing.JFrame;
 
 
public class GUIThread extends JFrame implements ActionListener{
 
 
public GUIThread(){
 
 
setSize(300,300);
 
setVisible(true);
 
 
JButton btn = new JButton("Button");
 
btn.addActionListener(this);
 
this.add(btn);
 
 
}
 
 
public static void main(String[] args) {
 
    // TODO Auto-generated method stub
 
            new GUIThread();
 
}
 
 
@Override
 
public void actionPerformed(ActionEvent arg0) {
 
// TODO Auto-generated method stub
 
System.out.println("Button");
 
 
MyThread x = new MyThread();
 
x.start();
 
 
}
 
 
}
 
</syntaxhighlight>
 
 
===Daemon thread===
 
Daemon thread in Java are those thread which runs in background and mostly created by JVM* for performing background task like Garbage collection and other house keeping tasks. Difference between Daemon and Non Daemon(User Threads) is also an interesting multi-threading interview question, which asked mostly on fresher level java interviews.
 
 
(*) A Java virtual machine (JVM) is an abstract computing machine that enables a computer to run a Java program.
 
 
* In one line main difference between daemon thread and user thread is that as soon as all user thread finish execution java program or JVM terminates itself, JVM doesn't wait for daemon thread to finish the execution. As soon as last non daemon thread finished JVM terminates no matter how many Daemon thread exist or running inside JVM.
 
 
* Another difference between daemon thread and user thread is that Daemon Thread are treated differently than User Thread when JVM terminates, finally blocks are not called, Stacks are not unwounded and JVM just exits.
 
 
* Thread inherits its daemon nature from the Thread which creates it (i.e. parent Thread). If the main thread is a non daemon thread, any other thread created from it will remain non-daemon until explicitly made daemon by calling '''setDaemon(true)'''.
 
 
* '''Thread.setDaemon(true)''' makes a Thread daemon but it can only be called before starting Thread in Java. It will throw '''IllegalThreadStateException''' if corresponding Thread is already started and running.
 
 
* Daemon Threads are suitable for doing background jobs like housekeeping, Though I have yet to use it for any practical purpose in application code. Let us know if you have used daemon thread in your java application for any practical purpose.
 
 
 
===Ejemplos clásicos para comprender el concepto de Thread===
 
Los siguientes problemas fueron abordados por el Prof. para explicar el concepto the Thread.
 
 
====Dining philosophers problem====
 
https://en.wikipedia.org/wiki/Dining_philosophers_problem
 
 
====Atomicity (database systems)====
 
https://en.wikipedia.org/wiki/Atomicity_(database_systems)
 
  
 
==Expanding our program across multiple files (Classes)==
 
==Expanding our program across multiple files (Classes)==

Revision as of 11:58, 10 June 2019

Path de los códigos:

Variable definida con:
{{#vardefine:codespath|/home/adelo/1-disco_local/.archivos_programas/eclipse-workspace/}}

Para usar la variable:
{{#var:codespath}}

Instalación de Java

Installing the Default OpenJDK

http://ubuntuhandbook.org/index.php/2018/11/how-to-install-oracle-java-11-in-ubuntu-18-04-18-10/

sudo apt update

sudo apt install default-jdk

Oracle Java Development Kit JDK

https://en.wikipedia.org/wiki/Java_Development_Kit

https://www.oracle.com/technetwork/java/javase/overview/index.html

Es apropiado instalar Oracle JDK. Para GUI Programming, por ejemplo, se necesitan librerías que se encuentran en Oracle JDK.

Hay diferentes Edition:

  • Java Platform, Standard Edition (Java SE) (ésta es la que generalmente necesitamos)
  • Java Platform, Enterprise Edition (Java EE)
  • Java Platform, Micro Edition (Java ME)
  • ...

Installing Oracle JDK on Ubuntu

Installing Oracle JDK (Java EE) on Ubuntu 18.04: http://ubuntuhandbook.org/index.php/2018/11/how-to-install-oracle-java-11-in-ubuntu-18-04-18-10/

En una ocasion, al instalar java-10-oracle la instalación de NetBeans no funcionó correctamente. Esto creo que se debía a que Java-10-oracle era muy reciente para la fecha. Fue por tanto necesario instalar java-8-oracle y configurar la ruta del JDK editando el archivo /usr/local/netbeans-8.2/etc/netbeans.conf

Installing Oracle JDK on Windows

Installing Oracle JDK (Java EE) on Windows:

  • Descargar Java SE de la página oficial de Oracle:
https://www.oracle.com/technetwork/java/index.html
https://www.oracle.com/technetwork/java/javase/downloads/index.html
  • Instalación común sin ninguna remarca.
  • Los archivos se guardan generalmente by default en: C:\Program Files\Java
    • Cuando instalé NetBeans, éste detectó automáticamente la ruta del JDK - JDK for the NetBeans IDE:
C:\Program Files\Java\jdk1.8.0_181

Check your installed java version

java  -version
javac -version


The fallowing command should tell you what is currently providing the Java virtual machine (java) and the Java compiler (javac): https://askubuntu.com/questions/150057/how-can-i-tell-what-version-of-java-i-have-installed

file /etc/alternatives/java /etc/alternatives/javac

Eclipse

Installing Eclipse

Para estar seguro de que estamos instalando la última versión, es apropiado descargar el paquete desde la página oficial, y no instalar la versión que se encuentra en los repositorios de Ubuntu a través de apt-get (pues estar versiones generalmente están desactualizadas).

Página oficial de Eclipse: http://www.eclipse.org/downloads/

En la siguiente página se explica como instalar eclipse en Ubuntu 16.04: http://ubuntuhandbook.org/index.php/2016/01/how-to-install-the-latest-eclipse-in-ubuntu-16-04-15-10/

Para instalarlo hay que simplemente ejecutar el instalador y seguir las instrucciones (como si se tratara de una instalación en Windows).

Luego, para agregar el ejecutable a la lista de comandos, he agregado la siguiente línea en el .bashrc:

PATH=$PATH:/home/adelo/1-system/.1-conf-system/1-archivos_programas-ubuntu/eclipse/java-photon/eclipse:

Combinaciones de teclas

  • Para que coloque los import (luego de haber ingresado un comando que necesite una librería en particular): Ctrl Shif o
  • Run: Ctrl 11
  • Comentar: Ctrl 7
  • Rastrea la variable seleccionada: CTRL k

NetBeans

https://netbeans.org/

https://en.wikipedia.org/wiki/NetBeans

Installing NetBeans on Ubuntu 18.04

https://www.itzgeek.com/how-tos/linux/ubuntu-how-tos/how-to-install-netbeans-ide-on-ubuntu-18-04-ubuntu-17-10.html

Se puede descargar NetBeans manualmente de la página oficial: https://netbeans.org/downloads/

o a través de wget:

wget http://download.netbeans.org/netbeans/8.2/final/bundles/netbeans-8.2-linux.sh

Luego:

sudo bash netbeans-8.2-linux.sh

Durante la instalación es importante seleccionar el directorio en donde se encuentra Java, en mi caso:

/usr/lib/jvm/java-8-oracle
/usr/lib/jvm/java-10-oracle

Con java-10-oracle la instalación no funcionó correctamente. Fue por tanto necesario instalar java-8-oracle y configurar la ruta del JDK editando el archivo /usr/local/netbeans-8.2/etc/netbeans.conf

Uninstall NetBeans

https://askubuntu.com/questions/76908/how-to-uninstall-netbeans

Sólo hay que ejecutar el script uninstall.sh in /usr/local/netbeans-x.x

bash uninstall.sh

Installing NetBeans on Windows 10

  • Descargar NetBeans de la página oficial: https://netbeans.org/downloads/
  • Cuando instalé NetBeans, éste detectó automáticamente la ruta del JDK - JDK for the NetBeans IDE:
C:\Program Files\Java\jdk1.8.0_181
  • Debido a que instalé la versión que tiene todos los componentes, se instaló también el GlassFish Server Open Source Edition. No sé para que es sirve y si sea apropiado instalarlo.

The Darcula plugin

In NetBeans IDE 8.2 you can now go to:

  • Tools > Plugins > Available Plugins > and install the Darcula LAF for NetBeans plugin directly from there.
  • En las versiones 9 y 10 el Plugin no se encuentra disponible por defecto. Es entonces necesario adicionarlo a la lista de "Available Plugins" de la siguiente forma:
https://stackoverflow.com/questions/52688439/changing-theme-in-apache-netbeans-9-0

Jar File

A Jar File (acronym for Java Archive) is format used for archiving java files (merging several java files into one)

The Jar File, provides a method to package our software to give it to the users.

The Jar File can be Runnable. That is, when we double click it, our program will run.


A typical extension to files that we have always seen when working in a Windows environment is the .exe file extension. These files are a single binary executable file that when double clicked will open the program for the user.

In the Java world however things are a little different. There is no native .exe file in Java and we must use the .jar file extension instead. A jar file works exactly the same as a .exe file and when double clicked will run the program.

Jar files come in two different varieties:

  • Simple archive folder
  • Runnable archive folder

A jar file is an acronym for Java Archive. Simple archive folder is a filetype similar to that of the .zip extension. If we want, we can open up a jar file using a program such as WinZip or WinRar and check the contents inside of the jar.

The second variant of this is the ​runnable archive folder​. This type of file is exactly the same as the archive folder, just with one additional file. This extra file is used to define what happens when the user double clicks on the icon. In our case, we will point to the main method in our class file that we want to run. This will kick start the program to run when it is double clicked.

Creating a Jar

Open up your Eclipse and navigate to the project you are currently working on. Note this will only work correctly with an application that has a GUI for the user to see. In this case the project we are looking at is called Sample Program 1.

  • Right click on the project name, and a menu will open.
  • In the menu that opens, click on the Export button.
  • In the window that opens you will see that two different types of JAR file are available:
    • If you wanted to simply package your project to give to someone, you could use the JAR file.
    • In our case, we are interested in the Runnable JAR file, so we will click on this option and then click Next.
  • You will then be passed to a second window where you will be able to specify the details for the runnable Jar file you are about to create:
    • The first of these is the launch configuration. This is the most important step to ensure that your Jar file will open the project when it is double clicked.
      • Select the name of the class you want to run, inside of the project that you have been working on. In this case, you can see that the Main class is selected which is inside of the project titled SampleProgram1 that we are working in.
    • The second step is then to select a location where we would like to export the Jar file to.
    • After you have finished, click Finish at the bottom of the page.
  • A small warning message may pop up, but this is ok. Click Ok to ignore this message.

Exploring the Jar File

Now that we have created the Jar file. If we double click on the file our program will run. However if we want, we can take a look inside of the Jar file. This is easily done by right clicking on the Jar file that we have created and clicking “Open with WinRAR” or whichever program you currently have installed on your system for viewing Zip files.

After WinRAR has opened you will be able to see the contents of the Jar file. In this case you can see the class file from the project that we have been developing. In addition to this, you will see an additional folder titled META-INF. This is the folder where all of the configuration for the Jar file are held. We will go into this folder and take a look around.

Inside of this folder, you will see a file titled MANIFEST.MF. This is the main configuration file for the Jar file we have created. If we open up this file, we can see the details of what is called when we double click on the Jar file to view it.

There is very little content that is needed to make the Jar file run. Inside of this file, you can see that the Main-Class attribute is set to the name of the class file that we want to run when the Jar is double clicked. In the case of this project, the class file that we want to run is called Main.class, so the title Main is used as the value for this attribute. If your class was called MyProgram.class, this would be set to MyProgram.

Expanding our program across multiple files (Classes)

Although we have developing all of our code inside a single java file, it is common practice to break the application down into smaller individual classes.

We will only ever have one main method. In this case, our Login.java is the file that will have the main method. No other class should have a main method!

Para integrar distintas «class» lo único que tenemos que hacer es tener los archivos en el mismo directorio y crear una instancia de la «class». En el siguiente ejemplo hemos creado una instancia de la «class» ShosingData en Login.java. En este caso, si se cumple el IF, se ejecutará «ShowingData.java».

Fracmento de /home/adelo/1-disco_local/.archivos_programas/eclipse-workspace/DBtest/src/Login.java
if(un.equals("Nathalie")){
        ShowingData d = new ShowingData();
}

Passing Object References

Ahora que nuestro programa está formado por diferentes archivos (diferentes class), veremos que en ocasiones, cuando creamos una «instance» de una class (Ej: «BasicShowData.java») dentro de, por ejemplo, «BasicLogin.java», podría ser necesario que «BasicShowData.java» colecte información de «BasicLogin.java». To do this, we will pass a reference across from the BasicLogin.java page to the «BasicShowData.java» page that will allow us to call back to the «BasicLogin.java» and access any variables or methods that it may have.

Note que inside «», when we click the "Login" button, the actionListener method is then called and the BasicShowData class is just being created. Instead of just creating the «BasicShowData()» class, we are going to pass a reference to «this» current class that we are in (BasicLogin.java class). En otras palabras, cuando en «BasicLogin.java» creamos la instance de «BasicShowData()» vamos a pasar una referencia de la clase donde estamos («BasicLogin.java») a través de «this»:

In BasicLogin.java:

BasicShowData d = new BasicShowData(this);

Now, in the «BasicShowData class», we must change the default constructor to catch «this» reference:

public BasicShowData(BasicLogin ref) {

De esta forma, la instancia de «BasicShowData class» puede acceder to all the variables and fields of the current class («BasicLogin.java»).

/home/adelo/1-disco_local/.archivos_programas/eclipse-workspace/PassingObjectReferences/src/BasicLogin.java
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class BasicLogin extends JFrame implements ActionListener{
	JTextField username = null;
	JTextField password = null;
	
	public BasicLogin(){
		
		setSize(300,300);
		setVisible(true);
		
		this.setLayout(new GridLayout(3,2));
		
		JLabel un = new JLabel("Username");
		this.add(un);
		
		username = new JTextField(20);
		this.add(username);
		
		JLabel pw = new JLabel("Password");
		this.add(pw);
		password = new JTextField(20);
		this.add(password);
		
		JButton button = new JButton("Login!");
		button.addActionListener(this);
		this.add(button);
		
		validate();
		repaint();
	}
	public static void main(String[] args){
		
		new BasicLogin();

	}
	@Override
	public void actionPerformed(ActionEvent arg0){
		// TODO Auto-generated method stub
		BasicShowData d = new BasicShowData(this);
	}

}


/home/adelo/1-disco_local/.archivos_programas/eclipse-workspace/PassingObjectReferences/src/BasicShowData.java
import javax.swing.JFrame;
import javax.swing.JLabel;

public class BasicShowData extends JFrame {

	public BasicShowData(BasicLogin ref) {
		
		String username = ref.username.getText();
		
		setSize(300,300);
		
		setVisible(true);
		
		JLabel tx = new JLabel("They logged in as: " + username);
		this.add(tx);
	}
}