gvSIG 2.0. Developers guide
- Introduction
- Maven
- Introduction
- Maven plugins
- Local and remote repositories
- Common tasks
- Lessons learned
- Disable unit tests
- Disable the updating of SNAPSHOT dependencies
- Debug unit tests
- Memory usage
- Use Maven through a proxy
- Available Maven resources
- Create a gvSIG project
- Before you start with developing a plugin
- Project structure in gvSIG
- Creating our project
- FortuneCookie, a gvSIG plugin
- Trabajar con un proyecto
- Preparar el espacio de trabajo en eclipse
- Tareas habituales con maven
- Versionado y publicación
- Instalables en gvSIG
- Introduction
- Packages and packages set
- Añadiendo nuestro paquete al repositorio de gvSIG
- Generando nuestro conjunto de paquetes
- Generando nuestra distribución de gvSIG
- El asistente para empaquetar plugins
- Librerías nativas
- Trabajar con el núcleo de gvSIG
- Introducción
- Compilar gvSIG
- Initial configuration
- Prerequisites
- Initial configuration of Maven
- How to create an Eclipse workspace for gvSIG
- Integración con eclipse
- Plataformas soportadas
- Compilar un grupo de proyectos
- Compilar un gvSIG completo
- Arrancar gvSIG
- Librerías nativas
- Java ME CDC
- Problemas conocidos
- Trabajando con un proyecto gvSIG
- Compilar mi proyecto
- Desplegar mi proyecto
- Publicar mi proyecto
- Generación de documentación e informes
- Cómo añadir o actualizar una dependencia
- How to create a gvSIG installer with installjammer
- gvSIG install build preparation steps
- Official version publishing of gvSIG
- Official version publishing of gvSIG Mobile
- Coding and Development Standards
- Coding conventions
- Nomenclature for classes and interfaces
- Names of packages used in gvSIG
- Logging
- Headers
- Migrating Projects to gvSIG 2.0
- Introduction
- Project name
- Migrating to maven and the new project structure
- Package nomenclature
- Logging
- Moving to Java >= 1.5
- Dependencies
- Persistence
- Cloning objects
- Initialisation of Libraries
- Extension points
- Fmap
- appgvSIG
- Installer
- Recommendations
- FAQs
- Where is MapControl's addMapTool method?
- What is equivalent to the FieldDescription class in version 2.0?
- What has happened to FLyrVect's getRecordset and getSource methods?
- Can't locate the View class?
- Where can I find the ViewPort's getAdjustedExtent method?
- How can I convert a geometry to JTS?
- Can't find getModel in the View class?
- How do I get an extension point?
- The createLayer method of the LayerFactory class is deprecated. How do I create a raster layer?
- Annexures
- Migration to the OSOR subversion repository
- Developing gvSIG 1.10+ projects with an eye on gvSIG 2.0
- FAQs
Introduction
Note
The 2.0.0 version of gvSIG is still under development. It is important to keep this in mind because there may be changes that could affect the development, this guide, as well as other development documentation.
The gvSIG developers guide aims to provide developers who will work with gvSIG all the information necessary to compile, edit and further develop gvSIG.
The main topics covered in the guide are:
- Maven: One of the major changes from versions prior to 2.0.0 is the use of Maven instead of Ant. Not only the compilation and construction of projects have changed with the switch to Maven, but also their structure.
- Create a project for gvSIG: how to create a new project, which may include libraries, extensions, etc, to develop with gvSIG.
- Working with a project: whether it is an existing project, or a project you just created, what will be the routine tasks to be performed during development.
- Generate installation files: what to do if we want our project to be installed on a binary gvSIG.
- Work with the core of gvSIG: it is preferable to work on a build or an installed version of gvSIG, but if we do not have one available, or if we need to change some core functionality, we can follow the steps in this section to prepare a work space and compile the gvSIG core.
- Coding and development standards defined by the gvSIG project.
- Migrate projects to gvSIG 2.0: For projects that worked on a previous gvSIG version and need to be migrated to 2.0, this section describes the main issues related to the migration.
Maven
Introduction
Maven is a tool for the management and construction of software projects, especially for those based on Java. Maven has similar goals to make and ant, but with greater emphasis on the configuration by convention.
Maven is hosted by the Apache Software Foundation, and can be found at: http://maven.apache.org.
The main goals of Maven are:
- Facilitate the process of compilation and construction of the project.
- Generate quality documentation for the project.
- Provide development guidelines based on best practices.
- To facilitate seamless migration to new features of Maven.
Setting up a Maven project is done through the pom.xml file, which describes the main properties of the project and its dependencies with other modules and external components, as well as the Maven configuration to be applied. On the Maven website there is a reference guide on the pom.xml file format
Following the philosophy of configuration by convention, Maven defines a standard project structure:
project |-- pom.xml `-- src |-- main | |-- java | `-- resources | `-- test |-- java `-- resources
If we follow this structure (but if it is different, it can be configured) with a basic configuration, we can perform the typical tasks of any Java project, already predefined in Maven:
- Compilation of code.
- Packaging in .jar, .war or .ear files.
- Generation of javadoc and other reports.
- Implementation of unit tests.
- etc.
Each task is determined by a Maven objective, with its name passed as a parameter. Example:
mvn install
There are two main versions of Maven: 1.0 and 2.0. The latter version is used in gvSIG.
Maven plugins
The functionality provided by Maven consists of a number of plugins that can be registered and configured for each project via the pom.xml.
The most commonly used plugins are registered and configured by default. If we use a different one for our project, or need to adapt the configuration of any existing ones, we can access the Maven plugins page.
For each plugin there is a user guide and documentation on the different parameters that are accepted by the plugin.
The Maven plugin page also provides links to other repositories of available plugins, mainly on codehaus.org and code.google.com.
Local and remote repositories
Maven manages two types of dependency repositories:
Local repository
Local disk location where Maven stores downloaded dependencies, so that they do not have to be downloaded every time. The structure corresponds to one folder per groupId (if the groupID contains points, a subfolder will be created for each element), a folder with the name of the artifactId and finally, a folder with the version.
The downloaded dependencies are stored in the folder of the version. For example, see the following dependency in a pom.xml:
<dependency> <groupId>org.gvsig</groupId> <artifactId>org.gvsig.tools</artifactId> <version>2.0-SNAPSHOT</version> </dependency>
This will be stored in the local Maven repository with the path:
MAVEN_REPO/org/gvsig/org.gvsig.tools/2.0-SNAPSHOT/org.gvsig.tools-2.0-SNAPSHOT.jar
The files stored by Maven in the local repository can be of type:
- pom.xml: the configuration and dependencies of the dependency. In this way, Maven will download the entire tree of dependencies that is needed at any given time so that we don’t have to specify the dependencies of a dependency of our project.
- .jar file with compiled classes.
- .jar file with source code.
- .jar file with javadoc.
- etc.
When specifying a dependency for our project, Maven will by default download only the .jar file with the compiled classes. However, we can specify that the .jar with the source code and / or the javadoc must be downloaded as well.
Remote repositories
Remote repositories are dependency servers where Maven will look when it cannot find a dependency in the local repository.
Common remote repositories that can be accessed via standard protocols are HTTP/S, FTP, SSH, etc.
The Maven project itself has a dependency repository, accessible by HTTP, which is configured by default. In the pom.xml files you can add other external repositories, or repositories of your own project. For example, gvSIG has its own repository, which is registered by default for the gvSIG projects, in addition to the official repositories.
The gvSIG repository is currently accessible through HTTP as read-only, and through SCP in editing mode. This repository contains mainly the files that are generated by the gvSIG projects, as well as any external dependencies that are not available in the official repository.
Common tasks
The Maven Getting Started Guide describes the common tasks, among which:
Compile a project:
mvn compile
Generate the artifacts (usually .jar files) and install them in the local Maven repository so that they are available for the other projects. This in turn implies the compilation, generation of .jar files, launching of tests
mvn install
Upload a generated jar (or jars) to the Maven repository, to publish a binary for the other projects:
mvn deploy
This option will be used when we have finished a version of a project that we want to publish so that it is accessible for other developers.
Delete everything that is generated with Maven, within the project:
mvn clean
Launch the unit tests:
mvn test
NOTE: Keep in mind that it is the virtual machine through which Maven is invoked that will launch the unit tests. This implies that, in general, we have the same requirements as gvSIG itself, such as having the JAI installed. This must be taken into account, also because the unit tests will be launched when generating a build.
Lessons learned
Disable unit tests
To launch Maven in a project and generate jars without launching the unit tests, add the following parameter:
-Dmaven.test.skip=true
Disable the updating of SNAPSHOT dependencies
When offline, or when you want to disable the updating of SNAPSHOT dependencies, add the -o parameter.
Debug unit tests
Sometimes we may need to debug the unit tests of a project, launched by Maven.
To do this, there is a parameter that causes Maven to wait for a remote debug connection on port 5005, before launching each test:
mvn -Dmaven.surefire.debug test
More information can be found in the documentation of the Maven debugging tests plugin
Memory usage
It is possible that for some of the tasks Maven launches, such as the compilation of Java classes, or the generation of Javadoc, the default memory settings will not be enough.
If this happens, an OutOfMemoryError message will appear in the console. We can increase the maximum memory allocation of the JVM by defining the MAVEN_OPTS variable that allows us to pass parameters to the JVM that launches Maven. For example:
Linux:
export MAVEN_OPTS=-Xmx256M
Windows:
set MAVEN_OPTS=-Xmx256M
When there is not enough space for the loading of classes (PermGenSpace), this will produce an error like:
[INFO] Compilation failure Failure executing javac, but could not parse the error: The system is out of resources. Consult the following stack trace for details. java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
In this case, we will need to increase the PermGen space with the -XX:MaxPermSize parameter. For example:
Linux:
export MAVEN_OPTS=-Xmx256M -XX:MaxPermSize=64m
Windows:
set MAVEN_OPTS=-Xmx256M -XX:MaxPermSize=64m
Use Maven through a proxy
If you access the Internet through a proxy, you will need to configure Maven to download dependencies through this proxy, following the Configuring a proxy instructions at the Maven page.
Basically, this consists of including the corresponding configuration in the .m2/settings.xml file:
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <proxies> <proxy> <active>true</active> <protocol>http</protocol> <host>proxy.somewhere.com</host> <port>8080</port> <username>proxyuser</username> <password>somepassword</password> <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts> </proxy> </proxies> </settings>
Available Maven resources
- The Maven project website: is the place where we can get the latest versions of Maven, general documentation and main plugins, etc.
- The dependency browser of the Maven project repository: this lets you search for artifacts from the Maven project repository that you may want to include as dependencies.
- The Codehaus plugin repository: the Mojo project of Codehaus develops additional plugins for Maven.
- The book Better Builds With Maven: the authors are some of the main developers of Maven, and we can download a free copy of the book after registration.
- Maven: The Definitive Guide: another book about Maven, available for reading online or as a PDF download under a Commons license.
Create a gvSIG project
Before you start with developing a plugin
When developing a project for gvSIG 2.0 we must consider several things if we want it to have the official endorsement of gvSIG and become part of the official gvSIG release.
Maven must be used as the tool to build the project.
Maven defines the group name, the groupId, and the identifier, the artifactId for the project. The groupID will be org.gvsig and the artifactId consists of the groupID followed by an identifier of the project.
For example, when creating a topography plugin for gvSIG, all the project packages will start with org.gvsig.topography.
The artifactId is used:
- To identify the root package of our Java project. All our packages begin with the artifactId.
- As name for our Eclipse project. Eclipse projects for gvSIG development have the same name as the artifactId.
- When naming the jars: the names of jars that are generated for our project begin with the artifactId followed by the version of the project and the Maven classifier.
There should be a strict separation between API and implementation.
This seems obvious, but very often there is no such separation, and when there is a separation it is usually not as strict as is required by gvSIG.
The main reason for this are issues such as:
How do we assess the scope of a change in the code? What would be the impact on the gvSIG application if we modify this?
Having the APIs strictly defined greatly facilitates the response to this question.
How can we properly document the use of libraries? When the API and the implementation are separated, it is easier to focus on the API documentation than when it is mixed with the implementation.
How can we run automated tests on our library? If we have a clear and well-defined API, we can focus on preparing automated tests to check the specifications of the API so that we can easily verify whether a change in implementation will affect the usage of the API.
There must be an automated test system to verify the functioning of the API in our project. Until now JUnit is being used to perform these tasks.
The APIs must be documented and this documentation must be uploaded to a public website.
For documentation of interfaces and classes of the APIs, Javadocs will be used. The API documentation should be complete and in English. To generate and deploy the documentation, the Maven tool for generating sites will be used.
The dependencies of our project on other libraries must be indicated.
This is done by keeping the ManageDependencies in the root of the Maven project updated.
The project must come with a test plan. This test plan should work by way of a series of acceptance tests that the project should go through after every gvSIG build until the final version.
User documentation of the project must be prepared in ReST (reStructured Text) format, preferably in English.
The jars of the project must be deployed in a Maven repository, and a versioning policy must be followed corresponding with the changes made to the project. gvSIG has its own Maven repository in which to deploy its libraries, but you can use another if appropriate.
A developers guide, preferably in English, to introduce developers in the use of the libraries of the project would be appreciated.
When generating installable packages of your plugin for gvSIG, make sure that it has a unique build number. There must be a way to uniquely identify a distribution or packaging of your plugin that does not leave any doubt to which version it applies. Therefore, a unique build number must be assigned to each packaging for gvSIG.
Project structure in gvSIG
Maven and Eclipse
One of the most interesting features of Maven is its ability to work with multi-module projects and the options for executing pre-defined targets to perform certain clearly defined tasks, such as code compilation and packaging.
Unfortunately, the current version of Eclipse does not include the necessary mechanisms to support multi-module projects, so that integration with the Maven mechanisms are complex and require the use of certain strategies to simulate such behavior.
Maven uses a Project Object Model (POM) to describe the software project to be built, the structure of the project and its sub-modules, their dependencies on other modules and external components, and the build order of the elements. Using these defined characteristics, you can get Eclipse to use the information in the POMs to simulate multi-module behavior.
Working with Maven in Eclipse
When working with Eclipse, as mentioned above, we will have to follow certain guidelines that will allow us to make use of the functionality Maven offers.
The first thing to note is the naming convention of the directories. The names applied to directories are not random, as they indicate the hierarchical structure of the project. Thus, the name of the parent project will be the name of the artifact_id, and its submodules will include the parent name (for example, if the parent project is org.gvsig.example, the submodule Example1 must be kept in the directory org.gvsig.example/org.gvsig.example.example1, and Example2 in org.gvsig.example/org.gvsig.example.example2. If Example1 has a submodule Example1a, it would be stored in org.gvsig.example/org.gvsig.example.example1/org.gvsig.example.example1a and so on). This gives the project a tree structure:
- org.gvsig.ejemplo
- org.gvsig.ejemplo.ejemplo1
- org.gvsig.ejemplo.ejemplo1.ejemplo1a
- org.gvsig.ejemplo.ejemplo2
- org.gvsig.ejemplo.ejemplo1
The parent nodes are not recognized as Java projects by Eclipse, because they are simply containers of the submodules. These projects contain the POM file with its definition and description of the submodules. In this way, you can launch commands at the parent module to run on that level and all its child nodes automatically (install, compile, etc.).
On the other hand, the child nodes (or leaves of the tree) are Java projects, with their usual project structure. These nodes can take advantage of the parent configuration (dependencies, properties, attributes, ...) if that parent is specified in the POM, simplifying its configuration.
Developing a gvSIG project
When we develop a gvSIG project there should be a strict separation between the API and the implementation of that API. To accomplish this, a basic template for gvSIG projects has been prepared which takes advantage of the Maven capabilities to manage multi-module projects. This template will guide us on how to organize the project, keeping strictly separated the logic of the extension from the user interface, and the API of the logic from its implementation, and the API of the interface from its implementation, in different Eclipse projects and separate jars.
The basic structure of a project will be:
- library
- tags
- branches
- trunk
- org.gvsig.example
- org.gvsig.example.lib
- org.gvsig.example.lib.api
- org.gvsig.example.lib.spi
- org.gvsig.example.lib.impl
- org.gvsig.example.prov
- org.gvsig.example.prov.provider1
- org.gvsig.example.swing
- org.gvsig.example.swing.api
- org.gvsig.example.swing.impl
- org.gvsig.example.main
- org.gvsig.example.lib
- org.gvsig.example
- extensión
- tags
- branches
- trunk
- org.gvsig.example.app
- org.gvsig.example.app.extensión
- org.gvsig.example.app
Compared to gvSIG projects prior to the 2.0 version, this project structure would seem rather complex, but we will look into it with more detail.
The first thing to note is that the project is oriented as a multi-module SVN project compared to what we used to see in the development of gvSIG 1.X. On the one hand we have the development of the library and on the other, the extension(s) for gvSIG. This has been organized like this because normally the changes in the logic of our extension usually have a life cycle that is clearly separated from the integration into gvSIG. After development of the extension has been completed, it is easier to do the modifications from one gvSIG version to the next in the parts of the code that contains the integration with gvSIG, while the logic remains unchanged except for some bug corrections. To achieve this independence, the SVN repository is separated into two main groups:
Library
This contains the logic and user interface that are independent of gvSIG as an application. This does not mean that they can’t depend on some gvSIG libraries such as the ones for data access, geometry or mapcontext. If they need to depend on those libraries, they can be used.
Extension.
This is the part of the code that depends on the gvSIG application, Andami and other gvSIG extensions. This is where the Extension classes are located, as well as the configuration of our Andami plug-in.
In the library we will find the following:
org.gvsig.example.lib
This provides the API, SPI, and the implementation of the API.
org.gvsig.example.prov
If our library needs to interact with a service provider, this is where the different implementations of these service providers would be located.
org.gvsig.example.swing
If our project includes a user interface for the library's logic, it would be located here only. The projects located into org.gvsig.example.lib must not depend on the user interface and, therefore, not on this project.
org.gvsig.example.main
You may find it strange to find a main module within the library, but it is actually quite useful. This is a module that provides a test application that you can use to launch the user interface and the logic of the library without having to start gvSIG to test it. This allows for a more agile development of our project, postponing the integration with gvSIG until it is in a more advanced stage of development.
And finally we come to the separation of some of these modules into API, SPI and implementation. This separation can be found in org.gvsig.example.lib and org.gvsig.example.swing.
Imagine that we are developing a network analysis extension for gvSIG. What projects would we be working with?
In principle, our project would not require special service providers. It would consist of the logic, the user interface, and the actual plugin for gvSIG. We would have the following projects:
- org.gvsig.networkAnalysis.lib.api
- org.gvsig.networkAnalysis.lib.impl
- org.gvsig.networkAnalysis.swing.api
- org.gvsig.networkAnalysis.swing.impl
- org.gvsig.networkAnalysis.main
- org.gvsig.networkAnalysis.app.extensión
Basically we would have these six projects, and each of them would generate its own jar, corresponding to the name of the project. Each of the projects will be will be located in its corresponding folder, and it is important that they have the correct name. This is because when you import these projects into Eclipse, we find that the folder tree is flattened; but thanks to the naming convention, these projects retain their consistency in our workspace.
Although it seems obvious, it should be pointed out which dependencies between those projects are acceptable. The implementation will depend on the API, but not vice versa. Also, our API should be concise and complete. Complete because the client of this API should not need to know the implementation in order to use it, and concise because the details of the implementation do not need to be exposed; the less details are exposed, the easier and safer the maintenance will be.
On the other hand, there is the user interface. This, whether the implementation or its API, should have no dependencies on the implementation of the library, or the logic. It should only depend on its API.
And finally, the test implementation and the extension can only depend on the API of the library and the user interface API.
It should also be noted that pom.xml files are found in each of the different folder. So there is a pom.xml in org.gvsig.example that allows us to interact with all the submodules of our project, and it contains the general configuration of the project. For example, through the pom.xml we can directly build the Eclipse projects for each of our modules. In turn, org.gvsig.example.swing and org.gvsig.example.lib have their own pom.xml files with their specific configuration. Finally, each of the final projects will have their own pom.xml file. Each of these pom.xml will be configured indicating the pom of the higher level folder as the parent pom to inherit the common configurations.
We have mentioned API several times. But what do we mean by API? How do we define it?
The question is not as obvious as it seems. When you ask several developers how they define an API module we can end up with very different answers. So, in gvSIG, how do we define an API? Normally, the API consists of a set of Java interfaces. There may be an abstract class that provides a default implementation for something that should be extended by the API user, but it never contains a class with its implementation. As usual, there are exceptions to this. By their nature, exceptions that trigger this API will be implemented in the API. This set of interfaces, packaged in a project and its jar, is the only dependency that the API user must depend on.
When using swing there will be differences. Swing lacks interfaces to handle graphic components, and therefore when it comes to defining the API of the swing part of our project, instead of using interfaces, we use abstract classes that extend the different swing components, adding abstract methods from our project domain. Usually there are abstract classes that extend JPanel, and these define the user interfaces associated with components of our project.
What does the implementation consist of?
Well, there we have a set of classes that implement the interfaces defined in the API. Normally there will be a manager which will serve as entry point to the functionality of our project and its configuration.
It is helpful to review the tools that org.gvsig.tools provides to manage the separation between API and implementation using the Library, Locators and Manager, and the tools that are available for the management of service providers, so that new projects will not need to reinvent each time how to implement these tools, and to harmonize their use throughout gvSIG.
We must also consider the recommendations when naming the classes and interfaces. The project structure described here is designed to follow a naming system such as described in the document nomenclature for classes and interfaces. So the API interfaces are named using meaningful names from the extension domain, without using any kind of prefix or suffix, while the classes that are found in the implementation project and which implement the API interfaces, are named by adding Default as a prefix to the name of the interface that they implement.
Before moving on to the creation of a gvSIG project according to the structure described above, it is recommended to review the documentation about org.gvsig.tools.service that describes in more detail the classes and interfaces to create, and how they are stored in a Maven subproject.
Creating our project
To work with our project need a gvSIG 2.0 installed. You must also install the Development project wizard addon, available through the addons manager (Tools > Addons manager).
What is going to offer this extension?
Mainly this extension will give us the option Create plugin. Using this utility, will allow the creation of maven projects, following the project structure described above, according to the custom options you choose to work with this installation of gvSIG.
This utility can be found in the menu Tools the option Development:
After accessing Create plugin option, the extension will show a wizard. This wizard will guide you to create a template from our maven project associated with this instance of gvSIG. As the most interesting points, note that the wizard will require that you enter the name of our project, group_id (default org.gvsig) and the location to generate the plugin.
You will have also to select the template to use, being able to select between a basic project with spatial support or a project to show fortune cookies. The first one is the recommended one.
If you select the second template, in addition we need indicate the type of plugin to be developed (for details see section FortuneCookie a _ plugin gvSIG). Finally, we will tell to wizard if we want to generate the extension for gvSIG or not.
As a last step in the generation of our plugin, the tool will perform a prepare_workspace to leave our project ready. Perform maven tasks 'configure-eclipse-workspace','maven install' and 'maven eclipse:eclipse'.
Once created the project, closing gvSIG, start Eclipse and import the folder we created the project. To work with it, we import the parent project (org.gvsig.<project_name>) as all sub-modules (org.gvsig.<project_name>.lib.api, org.gvsig.<project_name>.lib.impl, org.gvsig.<project_name>.main and others according to the variant chosen).
Once the project has been imported into Eclipse, we'll just create our plugin and boot normally, using the project build.xml file, and using the mvn-install target.
Finally, once developed our plugin, use the Pack plugin option of gvSIG installation. A utility to generate binaries from our plugin and will allow us to distribute it as a separate plugin or included in an existing gvSIG installable.
FortuneCookie, a gvSIG plugin
The FortuneCookie project is a very simple example plugin that aims to serve as a template to be followed by the developer when implementing their own plugins.
But, what advantages gives us the use of the diferents FortuneCookies projects? In principle, the most direct benefit is pretty obvious, since the fact of working on fully implemented a complete project that compiles and runs, can focus more on developing the code than in configuration tasks. And is that all FortuneCookies projects have declared their POM files with all the minimum dependences to run, and to establish relationships between them.
Therefore, to say that we have a project that will provide a number of basic, complete, compilable and run structures from which begin our development.
It presents several implementations that allow the developer show the highlights to be covered by your plugin depending on which option best suits the nature of the project. The variants presented are:
- Basic. Develop the essential elements in any project, such as the API and implementation.
- With service providers. Presents the necessary structure to implement a plugin that makes use of service providers to perform their functions. It gives the basic variant of the SPI definition and implementation of two providers: one through FortuneCookies provided by a Web service, and another from a local text file.
- With graphical user interface (GUI). Add the basic variant the entire structure to develop the GUI project. Provides the API and implementation Swing module responsible for the GUI, among which is the definition of the panels and the various tools for management and visualization.
- With service providers and GUI. This project join the above two points into one.
Should you require more information on any of the alternatives mentioned are advised to consult the document org.gvsig.tools.service
Moreover there is the option of GUI providers. This will be the option if, in addition to the above, support is required for the acquisition of user interfaces provided by vendors (currently under construction).
Trabajar con un proyecto
Preparar el espacio de trabajo en eclipse
Attention!
Pendiente
Tareas habituales con maven
Attention!
Pendiente
- Compilar
- Tests unitarios
- Instalar
- Javadoc
- Site
- Obtener árbol de dependencias
- Otros
Versionado y publicación
Instalables en gvSIG
Introduction
Warning
This document is under construction.
Note
The utilities described in this document are designed and tested on a linux system. It is very likely to work on other systems, but it is easy to require some adjustments.
Installing gvSIG is a hybrid mechanism between a native installer, dependent on the platform we are running, and a java installer. The native installer, will install the gvSIG framework, preparing everything necessary in order to start a minimalist installation. The second, the java installer, is responsible for presenting the user the different packages available for installation, and installed.
The whole system is based on plugins installation packages, bundles and how they are installed.
We find:
The native installer.
Install Packages plugins, a plugin for each package, * files *. gvspkg
Set of packages, which contain several installation packages plugins, gvspks files.
References to package plugins files that contain gvspki Basic data of the package along with the URL from where to download this.
A distribution of gvSIG is formed by the native installer, and a package set, gvspks, which added to the minimal installation a set of features we want to be in distribution.
They are available to those who need it, the mechanisms for creating gvSIG distributions with a custom packages sets, so that packages can be included as considered appropriate, thus creating distributions gvSIG specific or customized for different sectors.
Packages and packages set
Note
The utilities described in this document are designed and tested on a linux system. It is very likely to work on other systems, but it is easy to require some adjustments.
gvSIG supports several types of packages. These packages can install different types of accessories.
Currently there is only one type of package available, the container of plugins. From now on, herein, when referring to packet will always be talking about a package that installs a plugin.
gvSIG has a plugin that allows us to generate a package of a plug installed in that instance of gvSIG. This is a simple way that a developer can generate plugins packages from the same gvSIG on which it is developing.
The packet generation tool will include all information in the folder where live the plugin and also allow us to select other files inside the gvSIG installation, and include an ant script to be executed as post-installation script.
In addition to their own files that make up the plugin, we provide some basic metadata to identify the package. These are:
Package Code: Is the name used by the folder where you install the plugin into gvSIG. Must be unique and should not have two packages with the same name, unless it were different versions of this.
Version. The version of the package. Normally follow the following schedule:
mayor[.minor[.revision[-classifier[-build]]]]
It is very important that no two versions of the same different package with the same version number.
Package name: This is the name displayed to the user. By convention this should always be in English.
Package description: Describes the functionality provided by the package. By convention this should always be in English.
Owner: Organization/person name who owns the content of package.
Source code url: Which contains the url where to find the plugin source code.
Dependencies: With the specification of the package dependencies over other packages.
Operating system: Contain information on the operating system on which you can run this package. For now, systems supported OS are "Windows", "Linux" and "All". his is important for packages that need native libraries for implementing some of their tasks.
Architecture: Indicates the hardware architecture for which is designed the package, usually will x86 and x86_64.
Jvm: Indicates the minimum version of Java Runtime Environment package required to operate.
package required to operate.
- Official, that indicate whether a package is official or not.
In the plugin directory, there will be a * file * package.info with all this information, as well as a folder * install * the script ant to the post-installation called * install.xml *, and all this is packaged in a zip file with relative paths to the folder where you live in the plugin.
Keep in mind that this zip file should never contain folder entries, only files. So if you create a package by hand without using the tool provided by gvSIG we tell the command * zip * the appropriate option to not include them.
To create our own packages of our plugins, simply will be compressed in a zip file the folder where the plugin, making sure they exist, the file * package.info *, the * install folder * and the file * install / install.xml * if we need it.
Once we created our package we can install it using the installer is completed, or we can serve for inclusion in a gvSIG custom installation.
Here is an example of what would contain an install package. Let specifically see the plugin install support for ECW in gvSIG:
$ unzip -l gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspkg Archive: gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspkg Length Date Time Name -------- ---- ---- ---- 4092 07-08-11 09:47 org.gvsig.raster.ermapper.app/lib/org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT.jar 23391 07-08-11 09:47 org.gvsig.raster.ermapper.app/lib/org.gvsig.raster.ermapper.io-2.0.0-SNAPSHOT.jar 28206 07-08-11 09:47 org.gvsig.raster.ermapper.app/lib/org.gvsig.jecw-2.0.0-SNAPSHOT.jar 655809 07-08-11 09:47 org.gvsig.raster.ermapper.app/install/files/native/libNCSUtil.so.0 430361 07-08-11 09:47 org.gvsig.raster.ermapper.app/install/files/native/libNCSCnet.so.0 72242 07-08-11 09:47 org.gvsig.raster.ermapper.app/install/files/native/libNCSEcwC.so.0 6120711 07-08-11 09:47 org.gvsig.raster.ermapper.app/install/files/native/libNCSEcw.so.0 25851 07-08-11 09:47 org.gvsig.raster.ermapper.app/install/files/native/libjecw2.0.0.so 1085 07-08-11 09:47 org.gvsig.raster.ermapper.app/install/install.xml 313 07-08-11 09:47 org.gvsig.raster.ermapper.app/package.info 363 07-08-11 09:47 org.gvsig.raster.ermapper.app/config.xml -------- ------- 7362929 12 files $
We observed that we have the file package.info containing the description of the package:
#
#Fri Jul 08 09:47:35 CEST 2011
state=devel
name=Formats: Ecw format support
buildNumber=23
official=true
code=org.gvsig.raster.ermapper.app
operating-system=lin
architecture=x86
java-version=j1_5
gvSIG-version=2.0.0
version=2.0.0-SNAPSHOT
type=plugin
description=Ermapper data provider for gvSIG
model-version=1.0.0
In addition to this there is a folder install with a file Install.xml, which contains the post-installation script of the package and a folder files, a folder with the files that should go elsewhere gvSIG installation of the outside of the folder plugin. The post-install script takes care of copying the files native to where it belongs and in this case set the symlinks to work native libraries correctly installed:
<project name="org.gvsig.plugin1" default="main" basedir=".">
<target name="main" depends="copy_files, link"/>
<target name="copy_files">
<copy todir="${gvsig_dir}">
<fileset dir="./files" includes="**"/>
</copy>
</target>
<target name="link" depends="checkos" if="linuxos">
<exec executable="ln" >
<arg value="-s"/>
<arg value="${gvsig_dir}/native/libNCSCnet.so.0"/>
<arg value="${gvsig_dir}/native/libNCSCnet.so"/>
</exec>
<exec executable="ln" >
<arg value="-s"/>
<arg value="${gvsig_dir}/native/libNCSEcwC.so.0"/>
<arg value="${gvsig_dir}/native/libNCSEcwC.so"/>
</exec>
<exec executable="ln" >
<arg value="-s"/>
<arg value="${gvsig_dir}/native/libNCSEcw.so.0"/>
<arg value="${gvsig_dir}/native/libNCSEcw.so"/>
</exec>
<exec executable="ln" >
<arg value="-s"/>
<arg value="${gvsig_dir}/native/libNCSUtil.so.0"/>
<arg value="${gvsig_dir}/native/libNCSUtil.so"/>
</exec>
</target>
<target name="checkos">
<condition property="linuxos">
<os family="unix" />
</condition>
</target>
</project>
The other files that appear are the plugin files themselves, their jars and resource files that may need such as the config.xml. In this case find:
- lib/org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT.jar. It contains the extension associated with the plugin, used to log into your * * Initialize the new data provider library for raster.
- lib/org.gvsig.raster.ermapper.io-2.0.0-SNAPSHOT.jar the implementation of new data provider.
- lib/org.gvsig.jecw-2.0.0-SNAPSHOT.jar, the java bridge library to the libraries native needed by the plugin.
- config.xml, the configuration file of the plugin.
Each plugin will provide the files needed for their operation.
Añadiendo nuestro paquete al repositorio de gvSIG
Una vez tenemos nuestro paquete, podemos entregarlo a nuestros usuarios o solicitar que sea incluido en el repositorio de paquetes de gvSIG, lo que es altamente recomendable, ya que de esta forma damos acceso a él a cualquier usuario que pueda estar interesado en él.
Para hacerlo tendremos que preparar un fichero índice con la extensión gvspki. Este fichero es en un zip similar al gvspkg pero que solo contendrá el fichero package.info con una ligera modificación. El fichero package.info, además de los datos descritos en el apartado anterior tendrá una entrada download-url, que será la URL desde la que poder descargar el paquete, gvspkg, por lo que antes de crear el fichero gvspki deberemos tener claro dónde vamos a alojar nuestro paquete, y una vez construido el fichero gvspki haremos llegar este a gvSIG para que se incluya en el repositorio.
Estos paquetes que solicitamos que se integren en el repositorio de gvSIG solo tienen que cumplir unas pequeñas reglas, principalmente de nombrado y versionado del paquete, no siendo preciso que sean desarrollos oficiales, siendo así una forma fácil de distribuir nuestros desarrollos entre los usuarios.
Puede encontrar más información sobre cómo puede solicitar incluir su paquete en el repositorio de gvSIG en Añadir un paquete al repositorio de paquetes de gvSIG.
Tal como vimos en el apartado Paquetes y conjuntos de paquetes vamos a ver ahora que es lo que contiene el fichero indice del paquete que añade el soporte para el formato ECW:
$ unzip -l gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspki Archive: gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspki Length Date Time Name -------- ---- ---- ---- 505 07-08-11 09:47 org.gvsig.raster.ermapper.app/package.info -------- ------- 505 1 file $
Como podemos obserbar unicamente tiene un archivo, y es el package.info. Este archivo cotendra:
#
#Fri Jul 08 09:47:36 CEST 2011
state=devel
name=Formats: Ecw format support
buildNumber=23
official=true
code=org.gvsig.raster.ermapper.app
download-url=http\://downloads.gvsig.org/download/gvSIG-desktop/pool/org.gvsig.raster.ermapper.app/gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspkg
operating-system=lin
architecture=x86
java-version=j1_5
gvSIG-version=2.0.0
version=2.0.0-SNAPSHOT
type=plugin
description=Ermapper data provider for gvSIG
model-version=1.0.0
Como vemos contiene la misma informacion que el package.info del fichero gvspkg mas una entrada indicando donde se encuentra este, download-url.
Generando nuestro conjunto de paquetes
Además de generar el paquete para nuestro plugin y solicitar que este sea añadido al repositorio de paquetes de gvSIG, puede resultarnos útil generar un conjunto de paquetes, gvspks con los distintos paquetes que estemos interesados en hacer llegar a nuestros usuarios, de forma que podamos dar un juego de funcionalidades personalizado.
Para eso bastara con crear un fichero zip en el que incluyamos los paquetes, gvspkg, o referencias a paquetes, gvspki que nos interese. Además dentro de este fichero zip podemos incluir información sobre qué paquetes queremos que estén marcados como recomendados o a instalar por defecto, cuando el usuario intente utilizarlo para instalarse nuevas funcionalidades desde él.
Para conseguir esto tendremos que crear un fichero de nombre "defaultPackages" en el que indicaremos, el nombre de los paquetes que queremos que sean marcados como paquetes recomendados o por defecto (uno por línea).
Cada línea tendrá el formato:
code[#versión[#build]]
De forma que presentará como paquete recomendado el que tenga el código de la versión y build que hayan sido indicados.
¿Qué queremos decir con paquete recomendado o marcado por defecto ?
Si durante el proceso de instalación de la aplicación se utiliza un gvspks en el que tenemos una entrada "defaultPackages", los paquetes que ahí se indiquen se marcarán como seleccionados de forma automática para que se instalen. Es una forma de ofrecer al usuario una instalación típica de paquetes en función de los paquetes disponibles.
Si, una vez instalada la aplicación, entramos en el instalador de complementos, este nos presentará en un color distinto los paquetes que se indiquen en el fichero "defaultPackages" del gvspks que se esté usando, de forma que el usuario pueda ser consciente de qué paquetes es recomendado que tenga instalados.
Hay que tener en cuenta que los paquetes que formen nuestro conjunto de paquetes pueden ser tanto paquetes en sí mismos como referencias a paquetes. Esto nos brinda la posibilidad de incluir de base una serie de funcionalidades, y referenciar a otras que se encuentren en la web y que se descargarán bajo demanda si el usuario solicita instalarlas.
Generando nuestra distribución de gvSIG
Una vez hemos sido capaces de crear el paquete para nuestro plugin, así como de crear un conjunto de paquetes que nos permita ofrecer a nuestros usuarios un juego de funcionalidades personalizado, nos sería útil empaquetar todo esto en un solo instalable de gvSIG para facilitar la descarga e instalación de nuestra distribución personalizada.
El mecanismo de instalación de gvSIG permite hacer esto. Para ello disponemos de utilidades para incluir un gvspkgs dentro del instalable nativo de gvSIG, de forma que este lo extraiga y utilice automáticamente durante el proceso de instalación, así como que lo deje preparado para ser usado por el instalador de complementos cuando concluya la instalación.
Además de incluir nuestro conjunto de paquetes, también nos permitirá añadir los instalables del jre a utilizar por la aplicación para que el usuario no precise descargarselo, en caso de que no disponga de la versión adecuada de el.
Tip
En algunas distribuciones del plugin org.gvsig.mkmvnproject no se ha empaquetado la herramienta gvspkg, puede descargarla directamente desde la web de gvSIG en la que se generan las distribuciones oficiales de gvSIG-desktop, dentro de la carpeta gvspkg.bin .
Dentro de la carpeta "scripts" del plugin org.gvsig.mkmvnproject, encontraremos:
Tip
Este script esta probado sobre S:O. Ubuntu, no teniendo claro que funcione sobre otra plataforma.
- Un fichero gvspkg. Se trata de un script python que nos permitirá manipular los paquetes y conjuntos de paquetes.
- Una carpeta gvspkg.bin con los ficheros de configuración necesarios y los binarios necesarios para manipular el instalable nativo de gvSIG.
Antes de utilizar esta utilidad copiaremos la carpeta gvspkg.bin a nuestro home con el nombre ".gvspkg.bin", y nos aseguraremos que el script gvspkg está en el path.
Supongamos que tenemos los archivos:
- El instalador nativo de gvsig para linux, gvSIG-desktop-2.0.0-2030-devel-lin-x86-online.bin , que podremos descargar desde la web de gvsig.
- El conjunto de paquetes que hemos personalizado para nuestra instalación, packages.gvspks.
Ejecutaremos el comando:
gvspkg mkinstall gvSIG-desktop-2.0.0-2030-devel-lin-x86-online.bin packages.gvspks
Esto nos creara el fichero gvSIG-desktop-2.0.0-2030-devel-lin-x86-custom.bin partiendo de nuestro instalador nativo e insertando en el nuestro packages.gvspks.
Si además queremos que se incluya el instalador del jre en el paquete, tendremos que conseguir primero el archivo de instalación correspondiente. Podemos descargarlo desde:
https://downloads.gvsig.org/download/gvsig-desktop/runtimes/java1.6/
Allí encontraremos:
- jre-6u26-linux-i586.bin - jre-6u26-windows-i586-s.exe
Con los instalables del jre de java para windows y linux.
Así para generar nuestro instalable para linux ejecutariamos:
gvspkg mkinstall --jrelin=./jre-6u26-linux-i586.bin --addjrelin gvSIG-desktop-2.0.0-2030-devel-lin-x86-online.bin packages.gvspks
Y nos crearía gvSIG-desktop-2.0.0-2030-devel-lin-x86-custom-withjre.bin con el instalable del jre incluido y nuestro conjunto de paquetes personalizado.
Si quisiésemos generar los binarios para windows ejecutariamos:
gvspkg mkinstall --jrewin=./jre-6u26-windows-i586-s.exe --addjrewin gvSIG-desktop-2.0.0-2030-devel-win-x86-online.bin packages.gvspks
Generándose el fichero gvSIG-desktop-2.0.0-2030-devel-win-x86-custom-withjre.exe .
Warning
Esta pendiente añadir utilidades para cambiar la imagen del asistente de instalación así como el readme.
El asistente para empaquetar plugins
Para crear un paquete que contenga nuestro plugin la aplicacion gvSIG dispone de un asistente. Este asistente se encuentra en el menu Herramientas opcion Desarrollo, y requiere que el plugin ya se encuentre desplegado sobre su misma instancia de gvSIG. Vamos a ver cuales serian los pasos para generar un paquete de forma simple.
Lo primero deberemos haber desplegado nuestro plugin sobre una instancia de gvSIG. Para la prueba vamos a generar un paquete de instalacion del plugin org.gvsig.centerviewpoint.
Con el plugin desplegado ejecutaremos gvSIG y seleccionaremos la opcion de menu "Herramientas -> Debvelopment -> Crear paquete de instalacion de plugin".
Ahora seleccionaremos el plugin org.gvsig.centerviewpoint de la lista de plugins que nos muestra el asistente.
y pulsaremos en siguiente.
Ahora nos preguntara por los datos del paquete, que son los que describimos en el apartado Paquetes y conjuntos de paquetes.
Una vez rellenados los datos del paquete correctamente, pulsaremos en siguiente.
Se nos preguntara si queremos habilitar el modo avanzado. En general contestaremos que no dejando el check sin marcar.
Tip
El modo avanzado no sera necesario siemrpe que todos los archivos que precise nuestro plugin para funcionar se encuentren en la propia carpeta del plugin, y mientras no necesitemos ejecutar codigo especifico mediante el script de post-instalacion.
Le daremos siguiente para continuar con el asistente.
Ahora se nos preguntara por el archivo de salida. Por defecto nos ofrecera un nombre para el paquete siguiendo las reglas de nombrado usadas en gvSIG y ofreciendonos como carpeta donde dejarlo la carpeta install de la instalacion de gvSIG. Asi mismo nos pregunta si queremos crear tambien el archivo indice gvspki. Si no se lo ponemos nos generara el fichero del paquete con el que podremos probar si se instala correctamente nuestro plugin o pasarselo a nuestros usuarios para que lo instalen.
Si queremos generar el fichero indice, gvspki, deberemos tener clara bajo que URL va a ser accesible el paquete, para introducir esta en nuesto indice. Asi marcariamos la opcion Crear indice, y en URL de descarga introduciriamos la url completa de donde descargar el fichero gvspkg que vamos a generar.
Una vez completado el formulario, daremos a siguiente para que se inicie la generacion de los ficheros del paquete.
En caso de que necesitemos incorporar en nuestro paquete archivos que estan fuera de la carpeta de nuestro plugin, o precisemos ejecutar codigo en el script de postinstalcion, en el momento que se nos presenta la opcion de si queremos habilitar el modo avanzado lo marcaremos.
Imaginemos que queremos generar un paquete para el plugin de GPE que precisa actualizar la libreria que lleva gvSIG de base kxml de la version 2.2.2 a la version 2.2.3. Para esto hariamos:
Seleccionaremos el plugin de GPE
Rellenaremos los datos relativos a este plugin.
Marcariamos el check de habilitar el modo avanzado
Se nos presentara un arbol con la estructura de archivos de la instalacion de gvSIG para que seleccionemos los que precisemos. Iremos al directorio lib y seleccionaremos kxml2-2.2.2.jar
Y pulsaremos en siguiente.
Nos aparecera un panel con el script de post-instalacion por defecto, que se encarga de copiar los ficheros seleccionados al sitio adecuado.
Warning
TODO Continuar por aqui.
modificar el script para borrar el jar antiguo.
Librerías nativas
Attention!
Pendiente
Trabajar con el núcleo de gvSIG
Introducción
En este apartado se definen los pasos necesarios para poder preparar un espacio de trabajo con el núcleo de gvSIG 2.0, así como compilarlo y generar instalables del mismo.
Note
si vamos a desarrollar un nuevo plugin o librería para gvSIG, es preferible trabajar con un build o instalable, y recurrir a esta opción sólo si no disponemos de binarios o tenemos que hacer alguna modificación sobre los proyectos del propio core.
Compilar gvSIG
Initial configuration
Prerequisites
Before starting the installation process and configuration of all the elements needed to operate gvSIG, it is recommended to review the basic starting points that are needed to make the process of running the application a successful experience.
First, this guide is based on the use of the open source multiplatform integrated development environment Eclipse, on which all the necessary processes for the preparation and support of gvSIG will run. The version that was used in the preparation of this tutorial is 3.2, so it is advisable to use the same version or higher.
It is also necessary to install any of the existing Eclipse plugins for working with Subversion, because there is no default support for developing such functionality. You may use the version of Subclipse or Subversive that is best suited to the version of Eclipse that you installed.
On the other hand, and to ensure the proper functioning of all the components that are used by gvSIG, you will need to have installed version 1.5 or higher of Java Virtual Machine (JVM) from Sun Microsystems. It is important to check that this is a version of SUN, as gvSIG will not function properly on virtual machines from other entities, like the one that comes with the Debian GNU systems. For everything to run well the following must be considered:
- In the Java preferences of Eclipse, indicate the JVM to be used to run projects.
- Verify that Eclipse has the correct JVM set in the initial configuration, as starting Eclipse with the wrong JVM version can cause problems when running gvSIG.
Finally, in addition to the Java virtual machine, gvSIG depends on a set of native libraries, among which are GDAL and PROJ. In case of Ubuntu, the libraries to be used are included in the distribution, and those can be installed through the corresponding package manager. The packages to be installed for the proper functioning of gvSIG are:
- GDAL: libgdal1-1.4.0, libgdal1-1.5.0 or libgdal1-1.6.0 package, depending on which is available in your distribution.
- GRASS (through GDAL): libgdal1-1.4.0-grass, libgdal1-1.5.0-grass or libgdal1-1.6.0-grass, depending on the GDAL version that you installed. When you install this package, it will also install GRASS.
- PROJ: proj package
For Windows or Mac, these libraries will be obtained through Maven when compiling and generating a build of gvSIG.
Once your computer meets these requirements, you can proceed with the installation of Maven and the creation of a workspace for gvSIG, since the other needed elements will be obtained by the built project of the application.
Initial configuration of Maven
Apart from having a JDK installed, there is no need for any special configuration to begin working with Maven on gvSIG, because the gvSIG build project will install everything that is needed, including Maven.
However, if you want to install Maven yourself, you can download it from the project website and install it following the installation instructions. Keep in mind that Maven version 2.2.1 or higher is required for gvSIG.
You may also need to configure Maven to access the Internet through an HTTP proxy; the configuration is shown on the Maven installation page.
If you use the Maven installation included in the build project, you can find this in the Maven subfolder.
Note
Maven tests in gvSIG are done with the version included in the build project; with another Maven version the build of the project may not function properly.
Whether you install it yourself, or use the version provided by the build project, the subdirectory bin will contain the mvn script, that you can use when you are using Linux, Mac or any other Unix version, and the mvn.bat file for if you are using Windows. The most convenient way (to be able to run it from the console) is by adding the script to the run path (usually by adding the directory build/maven/bin to the PATH variable) so that you can run it from anywhere.
Later on we will describe some common tasks that can be used, either from a console or through the launchers from the External Tools menu in Eclipse.
gvSIG employs several native libraries, which are needed both for compilation and when running the application. Since they are native, you must use those that correspond to the platform on which you are compiling gvSIG.
A small configuration is needed to indicate the platform details to Maven, so that it can load the corresponding native libraries when compiling gvSIG. To do this, create a file .gvsig.platform.properties in your user's home directory with the following contents:
native_platform=linux native_distribution=all native_compiler=gcc4 native_arch=i386 native_libraryType=dynamic export native_classifier=${native_platform}-${native_distribution}-${native_compiler}-${native_arch}-${native_libraryType}
The first 5 values are the important ones; their meaning is explained in the section on compiling native libraries.
The currently supported values, i.e. for which the native libraries are already compiled and available, are:
platform | distribution | compiler | arch | libraryType | Comentarios |
linux | all | gcc4 | i386 | dynamic | Versión de 32 bits (equivalente en general a una Ubuntu-10.04) |
win | nt | vs8 | i386 | dynamic | Versión de 32 bits, compatible con windows XP, Vista y 7. |
mac | 10.5 | gcc4 | universal | dynamic | Plataforma todavía no disponible. Está en proceso de preparación y pueden variar alguno de los parámetros de la plataforma. |
This configuration allows us to work directly with the configuration of the project that has been prepared to integrate Maven with Eclipse for gvSIG. If we invoke Maven from the command line, we will need to introduce these parameters to Maven in a different way. There are two options:
Include the native-classifier and the native-platform variables values each time you invoke Maven. Example:
mvn -Dnative-classifier=linux-all-gcc4-i386-dynamic -Dnative-platform=linux install
Define an environment variable MAVEN_OPTS that includes the native_classifier variable. In Linux, for example, it would be enough to include the following in the .bash_rc file:
if [ -f "${HOME}/.gvsig.platform.properties" ] then . ${HOME}/.gvsig.platform.properties export MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=64m -Dnative-classifier=${native_classifier} -Dnative-platform=${native_platform}" else export MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=64m" fi
With this we can directly pass the platform values to Maven from Eclipse and to Maven from the console. For other operating systems you can pass the value directly to the native_classifier in the definition of the environment variable, but if you change the platform value, you must remember to change it for both cases (from Eclipse and from the console).
In addition to the platforms for which compiled native libraries are available, you can compile them by following the steps indicated in the document compilation of native libraries, and configure the parameters of the .gvsig.platform.properties file or the corresponding environment variable.
Those who are responsible for publishing binaries, source code or gvSIG project documentation will need to configure Maven to have write access to the server which hosts the gvSIG Maven repository through SCP (SSH).
To do this you must configure the Maven settings.xml file with the necessary information to access the Maven repository of gvSIG. This file is located in the USER_HOME/.m2 /, where USER_HOME is the user's home directory, which depends on the operating system that you are using.
If this is the first time you use Maven 2, you will need to create this folder as well as the settings.xml file manually.
The file needs an entry to configure the access to the gvSIG server, which is indicated with its ID gvsig-repository. Since the access is through SSH, we need to include the username and password:
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <servers> <server> <id>gvsig-repository</id> <username>[USUARIO]</username> <password>[CLAVE]</password> <filePermissions>666</filePermissions> <directoryPermissions>777</directoryPermissions> </server> </servers> </settings>
Note
It is important to include the permission settings as indicated in the example above, because with every file that is uploaded, the user and group that uploaded it is specified to prevent other users from uploading modifications to the same file. In any case, a script on the OSOR server will update the file permissions on a daily basis.
If you do not want to show the password in the previous file, Maven can encrypt passwords from the latest versions onwards. To do this, follow the steps described in the Maven documentation on Password Encryption
To summarize, the steps are:
Create a master password to encrypt the server passwords with this command:
mvn --encrypt-master-password <clave-maestra>
This will return the encrypted password, something like:
{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}
Keep the master password in the file [USER HOME]/.m2/settings-security.xml (create the file if it doesn’t exist yet) with the following content:
<settingsSecurity> <master>[CLAVE MAESTRA ENCRIPTADA]</master> </settingsSecurity>
Using the example from the previous step, it would be something like this:
<settingsSecurity> <master>{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}</master> </settingsSecurity>
Encrypt the password to access the OSOR server:
mvn --encrypt-password <clave>
Which will return something like:
{COQLCE6DU6GtcS5P=}
Substitute the open password with the encrypted password in the [USER HOME]/.m2/settings.xml file:
<server> <id>gvsig-repository</id> <username>[USUARIO]</username> <password>[CLAVE ENCRIPTADA]</password> </server>
Following the previous example, it would result in something like this:
<server> <id>gvsig-repository</id> <username>USER</username> <password>{COQLCE6DU6GtcS5P=}</password> </server>
How to create an Eclipse workspace for gvSIG
The steps for creating an Eclipse workspace for working with gvSIG are as follows:
Start Eclipse and create a new workspace for gvSIG 2.0.
Set the encoding used in gvSIG (ISO-8859-1):
Window > Preferences: General > Workspace > Text file encoding = ISO-8859-1
Set compatibility with Java 1.5 / 5.0 for all the projects (those which are compatible with Java ME CDC also have compatibility with Java 1.4):
Window > Preferences > Java > Compiler > Compiler Compliance Level = 1.5 (or 5.0).
In Eclipse, register the subversion repository in which we will be working.
It is possible to access to the subversion repository in two different ways:
- Anonymous access with read only permission.
- Access with read and write permission. For this you need a user in the infrastructure of gvSIG.
The access URL is: https://devel.gvsig.org/svn/gvsig-desktop.
Because a default installation of Eclipse does not provide support for subversion, it is necessary to install plugins for doing so:
Note
It is important to take note of the subversion plugin's version or configuration, and to ensure that is the same version as the subversion client in all cases: command line, Eclipse, etc. This is because with each new version of subversion the local format of the information changes, and backward compatibility is not maintained.
In other words, if a subversion 1.6 client is used for doing a checkout or an update, an older version (1.5. 1.4, etc.) will not work correctly if it is used subsequently.
If internet access is through a proxy, this must first be configured in Eclipse. To do this select the option:
Window > Preferences > General > Network Connection
Proxy access to the network can be configured in the preferences window. It is possible to choose either System proxy configuration or to specify a Manual proxy configuration and then manually set the connection values.
To register the choosen subversion repository, open exploring perspective of the subversion repository. If it is not available, it can be accessed from:
Window > Open Perspective > Other : SVN Respository Exploring
Once the perspective has been opened, it is possible to add the gvSIG repository from the SVN repositories view.
From this point onwards project locations within the gvSIG subversion repository will be referred to. The repository has the usual subversion structure:
- trunk: latest development version.
- tags: closed versions and builds, for which a tag is generated.
- branches: development branches.
From here on, the subversion paths will show [Repository]/[VERSION] rather than indicating the repository, and if trunk, tags/v2_0_0_Build_2007, etc. Keep in mind that at the time of writing, version 2.0 is being developed in branches/v2_0_0_prep branch, which is where projects can currently be downloaded, even though they will in future be moved to the trunk.
Download the build project.
To do this, one must apply a checkout from the source repository. From the SVN Repository view, navigate to:
[VERSION] (ej: branches/v2_0_0_prep)
Select the build folder and apply a checkout by clicking on the left button on the folder and selecting the appropriate option. In the checkout dialog, accept the default options and click Finish.
Once finished, the project will be available in the Java or Resource perspective.
Alternatively, the following command can be executed from the console:
svn co https://devel.gvsig.org/svn/gvsig-desktop/branches/v2_0_0_prep/build
As with Eclipse, if internet access is through a proxy, the subversion client must be configured to connect to the server through the proxy. The configuration instructions are available in the FAQ of the official subversion web, or in the section on configuration of servers in the subversion book.
Once the build project has been downloaded from the console, it can be imported into Eclipse.
Open the Ant view by selecting the following menu option:
Window > Show view > ant
Install the basic configuration of Maven for gvSIG.
The build project contains the basic Maven configuration for all the gvSIG projects in a general pom.xml, as well as specific configurations for each project type:
- library: build/libraries-pom/pom.xml
- native library: build/libraries-jni-pom/pom.xml
- extension: build/extension-pom/pom.xml
Initially, and each time that any of these files are changed, these files must be installed in the local repository of Maven. There are two ways of doing this:
Eclipse: Add the build.xml file in the build project to the open Ant view. A number of Ant objectives will appear, amongst which is mvn-install. This is launched by double clicking or by selecting the required objective and clicking the icon.
Console: from the build folder, launch:
mvn install
Configure Eclipse to correctly load the projects generated from Maven.
To do this, from the Ant view invoke the objective: mvn-configure-eclipse-workspace. This will automatically create an environment variable in Eclipse, which is used to refer to the jars of the dependences managed through Maven. It will ask for the location of the workspace, which usually will be the default.
Alternately, from the console it is possible to use Maven as follows:
mvn -Declipse.workspace=<path-to-eclipse-workspace> eclipse:add-maven-repo
Then close Eclipse and open it again.
Check that the M2_REPO variable is correctly defined in Eclipse. From the menu select:
Window > Preferences : Java > Build Path > Classpath Variables
The variable value must be something like (replace [USER_HOME] for the user's folder, according to the Operating System):
M2_REPO = [USER_HOME]/.m2/repository
To the Ant view add the build.xml file from the group of projects that you are going to work on. Groups of Projects will be explained in detail at a later stage but for now think of them as lists of projects (libraries and extensions) which are in the build/projects folder.
If the intention is to download the projects of a complete gvSIG, add the following file to the Ant view:
build/projects/gvsig-standard/build.xml
Start downloading the projects.
To do this, from the Ant view invoke the objective: svn.checkout.all. A form opens where it is possible to select:
- The URL of the subversion server, which depends on whether public access with read only rights, or access with read and write rights (which requires a user name and password) is preferred.
- The SVNKit version to use. It is necessary to check that this is the same as that of the subversion support plugin installed in Eclipse. As in the previous cases, accessing the Internet through a proxy requires the access for the SVNKIT library to be configured. In fact, this library reads the same configuration as the native client of subversion, whose configuration is described in Download the build project. More information is available in the users guide of SVNKIT
- User name and password to access subversion, if applicable.
- Whether to automatically create the Eclipse project configuration once the download is complete. If this option is deactivated, the Eclipse projects have to be generated either from the mvn eclipse option on the External tools menu or from the console with the instruction: mvn -P eclipse-project.
Alternatively, it is possible to invoke this Ant objective from the console, or to do a checkout of each project, from Eclipse or from the console. In the latter case, it will be also be necessary to generate the Eclipse project configuration.
Import the projects into Eclipse. Once the previous step is complete the projects can be imported into Eclipse by choosing the following menu option:
File > Import > General > Existing projects into workspace
Click on Select root directory and select the workspace directory. The list showing the projects to import will appear and, after accepting them, Eclipse will proceed to compile the imported projects.
Note
when importing the projects, check that the option Copy projects into workspace is deactivated, because the intention is to use the same projects which have been downloaded directly.
The eclipse plugin for maven does not link eclipse projects between them until they are already imported into the eclipse workspace, so we must regenerate the projects eclipse configuration.
From the Ant view, select the mvn-eclipse-eclipse goal. Once the process has finished, select all projects and refresh them (F5 o press the right button and select the Refresh option).
Finally, the eclipse plugin for maven generates the eclipse plugin configuration only for the java projects, that is, the projects which have java code. As there are some multimodule projects, only the eclipse project configuration of the submodule final children will be generated. As an example, the org.gvsig.annotation project has the following structure:
org.gvsig.annotation ├── org.gvsig.annotation.lib │ ├── org.gvsig.annotation.lib.api │ └── org.gvsig.annotation.lib.impl ├── org.gvsig.annotation.main └─── org.gvsig.annotation.swing ├── org.gvsig.annotation.swing.api └── org.gvsig.annotation.swing.impl
If we look at the current imported projects, we will find only the following ones:
- org.gvsig.annotation.lib.api
- org.gvsig.annotation.lib.impl
- org.gvsig.annotation.main
- org.gvsig.annotation.swing.api
- org.gvsig.annotation.swing.impl
We need to have, at least, each root parent project to be able to update everything when synchronizing from subversion, as well as allowing us to perform actions to all the submodules of the same project.
There is only one way that we are aware of to be able to import those root parent projects:
Select the eclipse menu: File > New > Project....
In the dialog, select the option: General > Project and click Next
In the following dialog, fill in the following form fields:
- Project name: The name of the parent root project to import. Ex: org.gvsig.annotation.
- Use default location: Select this option.
Finally click Finish and the project will be available in eclipse. Its not a java project, so we must not edit java files from it, but through the subprojects. Those root projects will be used only to perform maven actions to all the submodules or to synchronize from subversion.
Those are the projects to import that way:
- org.gvsig.annotation
- org.gvsig.annotation.app
- org.gvsig.app.document.layout.app
- org.gvsig.app.document.table.app
- org.gvsig.exportto
- org.gvsig.exportto.app
- org.gvsig.geometrymeasurement.app
- org.gvsig.hyperlink.app
- org.gvsig.installer
- org.gvsig.installer.app
- org.gvsig.newlayer
- org.gvsig.newlayer.app
- org.gvsig.personaldb
- org.gvsig.selectiontools.app
- org.gvsig.symbology
- org.gvsig.symbology.app
Note
This final step is certainly cumbersome, but we haven't found a more authomatic way to perform it. We had already tried to commit to subversion the .project files of those root projects but then, in the initial eclipse import of all the gvSIG projects, only the root projects are included. You had to import then each child submodule one by one, which is still worse. The maven plugin for eclipse could be used to solve that problem, but is has other problems still to be solved.
Integración con eclipse
En el momento de preparar esta guía, Eclipse no lleva soporte de forma oficial para maven. Existen algunos plugins disponibles que permiten integrar maven en eclipse, aunque parece que todavía no son completamente funcionales. Uno de ellos (Q4E), de hecho, está en proceso de ser incorporado a eclipse de forma oficial, bajo el nombre Eclipse IAM, pero todavía no ha sido liberado.
Por no ligarnos a un plugin no oficial de eclipse, por ahora se va a emplear una integración básica de eclipse con maven, que permita en cierta forma compartir la configuración de proyecto de maven con eclipse, así como invocar a maven desde el propio eclipse.
Note
si nos hemos descargado el workspace siguiendo las instrucciones del documento Cómo montar un workspace con Eclipse (ver documentos relacionados), ya tendremos el workspace preparado.
Para que el eclipse sea capaz de encontrar el repositorio de maven es necesario configurar la variable en el workspace. Esto lo podemos hacer de forma sencilla empleando el plugin eclipse de maven, con el objetivo:
mvn configure eclipse workspace
Al hacerlo desde eclipse, ya tomará por defecto el valor del path del workspace sobre el que estamos trabajando.
Si queremos lanzarlo desde consola, la instrucción es:
mvn eclipse:add-maven-repo -Declipse.workspace=WORKSPACE_PATH
En 'WORKSPACE_PATH' especificaremos la ruta absoluta al workspace.
Note
los proyectos generados desde eclipse con los objetivos create library y create extension ya generan también automáticamente el proyecto de eclipse.
Si tenemos un proyecto configurado con maven, no es necesario crear manualmente el proyecto de eclipse, ya que maven puede generarlo por nosotros. Para ello bastará con usar el siguiente objetivo:
mvn eclipse
Desde consola, la instrucción equivalente es:
mvn -P eclipse-project
Note
La forma habitual de generar un proyecto de eclipse desde maven es emplear la instrucción mvn eclipse:eclipse. Sin embargo, para algunos proyectos, como los que generan varios jars en los que se incluyen clases de tipo Library, el plugin de maven que genera los proyectos de eclipse no es capaz de generar toda la configuración necesaria, por lo que se ha creado un perfil desde el que se invoca al plugin de eclipse y, además, añade el resto de configuración necesaria. Si en algún caso se creara el proyecto de eclipse sin usar el perfil eclipse-project, el único problema es que los tests unitarios que empleen el mecanismo de inicialización automática de librerías no funcionaran si los lanzamos desde eclipse.
Esto generará los archivos de eclipse necesarios, que nos permitirán importar el proyecto desde eclipse, con todas las dependencias, directorios de fuentes, etc. ya definidos.
Si ya existe el proyecto de eclipse, el objetivo anterior no lo sobreescribe, para ello tenemos que emplear antes el objetivo:
mvn eclipse clean
O desde consola:
mvn eclipse:clean
En los proyectos de gvSIG, está configurado de forma que, además de descargar y enlazar las dependencias binarias (jars con clases) en el proyecto de eclipse, maven intentará descargar también los jars con los fuentes y los javadocs correspondientes, enlazándolos a cada jar de binarios. Esto nos permitirá ver fácilmente la documentación y el código fuente de las dependencias de nuestros proyectos.
Por otro lado, si generamos los proyectos de eclipse para un grupo de proyectos, maven nos enlazará las dependencias entre los proyectos del grupo a nivel de proyecto, en vez de a nivel de archivo jar.
Esto permite que los proyectos de eclipse no se suban al repositorio de fuentes de gvSIG, ya que se pueden generar fácilmente para un proyecto o conjunto de proyectos.
Para facilitar el uso de maven desde eclipse, se han preparado una serie de lanzadores con los objetivos más usados en los proyectos con maven.
Dichos lanzadores están definidos dentro del proyecto build, por lo que una vez incluido este proyecto en nuestro workspace de eclipse, los tendremos disponibles automáticamente.
Para lanzar cualquiera de ellos deberemos tener abierto el proyecto sobre el que queremos trabajar, y seleccionar el lanzador correspondiente desde la opción de Herramientas externas (External Tools).
Eclipse no detecta una dependencia en el repositorio de maven, aunque el jar correspondiente sí que existe en disco
Por alguna razón, parece que Eclipse no se da cuenta de cambios en librerías de dependencias que están puestas a través de una variable de entorno. Incluso refrescando y recompilando el proyecto a veces no detecta el jar correspondiente.
Una forma que suele funcionar consiste en:
- Cerrar el proyecto.
- Abrir el proyecto.
- Recompilar el proyecto.
Plataformas soportadas
platform | distribution | compiler | arch | libraryType | Comentarios |
linux | all | gcc4 | i386 | dynamic | Versión de 32 bits (equivalente en general a una Ubuntu-10.04) |
win | nt | vs8 | i386 | dynamic | Versión de 32 bits, compatible con windows XP, Vista y 7. |
mac | 10.5 | gcc4 | universal | dynamic | Plataforma todavía no disponible. Está en proceso de preparación y pueden variar alguno de los parámetros de la plataforma. |
Compilar un grupo de proyectos
Maven permite trabajar con lo que llama multimódulos o una estructura multiproyecto. Esto nos permite lanzar una orden de maven sobre un grupo o jerarquía de proyectos, desde una única llamada a éste. Para ello tenemos un pom.xml que hace referencia a un conjunto de proyectos de maven.
La estructura habitual consiste en tener una organización en árbol de proyectos, pero también podemos tener una estructura plana, en el que el proyecto que contiene el pom.xml en el que se hace referencia al resto de proyectos se encuentra a la misma altura que estos.
En gvSIG la estructura de proyectos que hay en el repositorio de fuentes no está pensada para ser descargada tal cuál, sino que se debe descargar proyecto a proyecto, con lo que tenemos una lista de proyectos todos dentro del mismo directorio.
Aunque en un futuro se podría migrar a una estructura multimódulo de proyectos, por ahora la vamos a simular mediante grupos de proyectos dentro del directorio build de gvSIG. Dentro de este, en el subdirectorio projects se han creado una serie de directorios, cada uno de los cuáles hace referencia a un grupo de proyectos:
build `-projects |-gvsig-base |-gvsig-cdc-compat |-gvsig-coverage |-gvsig-coverage-base ...
Si accedemos a uno de estos directorios, vemos que contienen un archivo pom.xml, el cuál hace referencia a un conjunto concreto de proyectos. Así, si desde aquí usamos maven, la orden se lanzará automáticamente para cada uno de los proyectos referenciados.
Este mecanismo nos permite, de forma cómoda, realizar operaciones de compilación e instalación sobre un conjunto de proyectos, o incluso generar un build de gvSIG completo.
El criterio para definir los grupos ha sido el de unir proyectos sobre una misma funcionalidad o cuyo desarrollo se realice de forma conjunta. Además, aprovechando que un pom.xml puede hacer referencia, tanto a proyectos sueltos, como a otros conjuntos de proyectos, se ha definido un grupo para la generación de un build completo con la unión de otros grupos.
Por ejemplo, si estamos desarrollando sobre GPE, actualmente está dividido en los siguientes proyectos:
- libGPE
- libGPE-XML
- libGPE-GML
- libGPE-KML
- extGPE-gvSIG
Si queremos compilarlos todos a la vez, bastará con ir al directorio gvsig-gpe y realizar la orden:
mvn compile
Esto realizará la compilación de los distintos proyectos de GPE, uno tras otro. Si, en alguno de ellos, se produce un error de compilación, el proceso se detendrá y no seguirá en los siguientes.
Dentro de cada uno de estos directorios de grupos de proyectos, tenemos también un script de utilidad que nos permite hacer un checkout de forma rápida de los proyectos del grupo. Por ejemplo, si queremos desarrollar sobre GPE, bastará con hacer un checkout inicial del directorio build y, a continuación, desde el subdirectorio projects/gvsig-gpe llamar al script svnco.sh, que se encargará de hacer un checkout de los proyectos de GPE.
Compilar un gvSIG completo
Aprovechando el mecanismo anterior de los grupos de proyectos, se han definido dos grupos que permiten trabajar con todos los proyectos de un build de gvSIG:
- gvsig-base: conjunto de proyectos básicos para tener un build de gvSIG mínimo con soporte vectorial sobre algunos formatos de archivo básicos. Se puede emplear durante el desarrollo de nuevas extensiones que no dependan de otros proyectos, sin cargar otras extensiones.
- gvsig-standard: conjunto de proyectos de un build estándar de gvSIG. Incluirá habitualmente el conjunto de proyectos que conformarán un build oficial de gvSIG.
A partir de ahora consideraremos que vamos a trabajar con la versión del build estándar.
Para compilar todo gvSIG usaremos maven, bien desde eclipse, bien desde consola. La forma habitual será mediante el objetivo install:
Eclipse: si no lo tenemos aún, añadiremos a la vista de Ant el archivo build/projects/gvsig-standard/build.xml y lanzaremos el objetivo mvn-install. De la misma forma, tenemos otros objetivos de uso habitual accesibles con este mecanismo, con su equivalencia en maven, como por ejemplo:
- mvn-clean
- mvn-install
- mvn-install-without-tests: equivalente a mvn -Dmaven.test.skip=true install
- mvn-reinstall: equivalente a mvn clean install
- mvn-reinstall-without-tests: equivalente a mvn -Dmaven.test.skip=true clean install
Al menos la primera vez deberían compilarse y lanzarse los tests unitarios en los proyectos que los tengan activados. El resto de veces, se puede hacer la compilación sin lanzarlos mediante el objetivo mvn-install-without-tests.
Consola:
mvn install
Esto compilará todos los proyectos e instalará todas las extensiones y sus archivos en la ubicación correspondiente.
Arrancar gvSIG
Los builds de gvSIG desde maven están configurados para ser generados en el directorio build/product, en vez de dentro del proyecto de _fwAndami como se hacía con ant.
Podemos lanzar gvSIG de dos formas distintas:
Eclipse: automáticamente, al haber incluido el proyecto build se nos habrán configurado una serie de configuraciones de arranque de utilidad. Para arrancar gvSIG seleccionaremos:
Run > Run Configurations > Java Application
De la lista de configuraciones, tendremos al menos las siguientes 3:
- gvSIG Linux
- gvSIG Mac
- gvSIG Windows
Seleccionaremos la que corresponda a nuestro sistema operativo. Esta configuración la podemos usar, tanto para ejecución normal, como para ejecución de gvSIG en depuración.
Estos launchers están configurados incluyendo en su classpath la lista the archivos .jar disponibles en la carpeta build/product/lib de forma individual, los cuáles se corresponden con el propio jar the andami más todas sus dependencias. Dado que dichos archivos se generan y copian a través de maven, algunas veces eclipse no se da cuenta de los cambios en dicha carpeta.
Algo que pasa algunas veces es que eclipse cree que no hay nada en la carpeta build/product/lib, y sin embargo sí que están los archivos. Entonces, al usar uno de los launchers eclipse nos da un error, algo como:
The archive: /build/product/lib/castor-0.9.5.3.jar which is referenced by the classpath, does not exist
Para solventarlo bastará con ir a la carpeta build/product/lib con el package explorer, project explorer o navigator de eclipse y refrescarlo. Entonces ya aparecerán los archivos jar necesarios y podremos lanzar el launcher de nuevo.
Consola: dentro del directorio build/product tenemos ya un gvSIG.sh, o un gvSIG.bat según corresponda, para arrancar el build de gvSIG que hayamos generado.
Librerías nativas
Introducción
Algunas de las extensiones de gvSIG, necesitan el uso de librerías nativas para su funcionamiento. El problema existente con este tipo de librerías es que es necesario tenerlas compiladas para cada plataforma y sistema donde se quiera hacer uso de gvSIG.
Para facilitar la distribución y construcción de estas librerías se ha integrado con el actual sistema de construcción basado en maven. Para ello se ha añadido funcionalidad a las fases de construcción. Es necesario entender que cuando se trabaja con librerías nativas existen tres partes claramente diferenciadas:
- Código Java: Código únicamente Java y que puede ser distribuido sin tener que recompilar para cada plataforma, éste código se compila de manera estándar y no necesita ningún tipo de tratamiento especial. Éste código será el encargado, mediante una API concreta y conocida de la máquina virtual, de cargar las librerías nativas.
- Código JNI: Código generalmente en C/C++ que hace uso de la API JNI(Java Native Interface). Éste codigo ya es dependiente de plataforma y requiere ser compilado para cada plataforma destino donde se quiera utilizar la librería.
- Dependencias nativas externas: En proyectos tan grandes, es habitual depender de otras librerías. En gvSIG el caso más claro es la librería GDAL. Estas dependencias requieren también estar compiladas para la plataforma destino y además se necesita tener acceso a su SDK, para poder compilar la parte JNI anteriormente mencionada.
Uso de librerias nativas ya compiladas
Un desarrollador java que trabaje sobre una plataforma para la cual existan librerías nativas ya compiladas no tendrá que preocuparse de hacer nada especial para el uso de estas. Estas nativas aparecen como dependencias de otras librerías java y serán descargadas a $HOME/.m2 cuando hagamos un mvn install del proyecto java que las incluya. Posteriormente, cuando se hace un mvn install -Pinstall-extensions de la extensión que hace uso de las librerías java, los binarios nativos de los cuales se dependa serán instalados en el directorio .depman de nuestro “home”.
Actualmente para que se reconozca la plataforma en la que estamos se ha de indicar explícitamente.
El proyecto org.gvsig.maven.base contiene un directorio org.gvsig.maven.base.pom con un fichero pom.xml donde podemos cambiar la plataforma, distribución, compilador y arquitectura sobre la que estamos funcionando en caso de que no nos vaya bien la que viene por defecto. Una vez hecho esto deberemos ir al raiz del proyecto y ejecutar mvn install para instalar los cambios en nuestro repositorio local.
Este proyecto puede descargarse de: https://svn.forge.osor.eu/svn/gvsig-tools
Compilación de las Librerías Nativas
Con esta pequeña introducción a la problemática de las librerías nativas a continuación se explica cómo compilar las librerías que actualmente se encuentras migradas a maven.
Para cada sistema, ya no sólo es necesario tener instalado el JDK y por supuesto maven (aunque se puede hacer uso del maven que se distribuyen dentro del directorio build). Es necesario descargarse los programas necesarios para compilar en cada sistema.
Para todos los sistemas es necesario descargarse e instalar CMake: http://www.cmake.org.
- Windows:
- Visual Studio 2005 (vs8)
- CMake
- Linux(Debian o Ubuntu):
- apt-get install build-essential
- apt-get install cmake
- Mac:
- Developer Tools distribuidas en el propio CD de MacOS X.
- CMake
Es necesario tener un workspace al menos con los siguientes proyectos:
- build
- org.gvsig.maven.base
- libjni-xxxx (todos los que queramos compilar)
Compilar Java: Es tan sencillo como lanzar la instrucción del directorio de la librería ( o el target ant asociado ). Automáticamente se descargará la librería JNI de la que depende y las librerías externas de las que depende desde el repositorio de maven:
Linux: mvn install -Dnative-distribution="all" Windows y Mac: mvn install
Compilar Java + JNI: Al igual que antes se compilará la parte Java y en este caso se compilará también la parte JNI, las dependencias externas se descargarán desde el repositorio de maven:
Linux: mvn install -Dnative-distribution="all" -Pjni-devel Windows y Mac: mvn install -Pjni-devel
Las librerías nativas necesitan siempre del parámetro -Dnative-distribution={mi distribución linux}. La razón por la que es necesario es que según que distribución para la que se haya compilado puede que requiera unas dependencias externas u otras, o incluso pueden ocurrir problemas de compatibilidad binaria con las librerías del sistema.
Si una distribución linux no está soportada o no se han subido al repositorio de maven las dependencias, entonces fallará la búsqueda de dependencias y dará un error, es por tanto responsabilidad de los mantenedores de las librerías subir esas dependencias para las distribuciones oficiales de gvSIG.
En Windows, se considera que el compilador por defecto es el Visual Studio 2005 (vs8), por tanto para poder lanzar la compilación es necesario abrir una Consola de Visual Studio 2005" para que se definan correctamente las variables de entorno del compilador.
Aunque el sistema se lanza y se maneja con Maven, internamente hace uso de CMake, una herramienta multiplataforma que permite la compilación y generación de proyectos de compilación.
Para poder subir ficheros al repositorio hay que tener configurado el fichero settings.xml de nuestro repositorio local ($HOME/.m2) con los valores correctos para el servidor. Un ejemplo de este fichero podría ser el siguiente:
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0" http://maven.apache.org/xsd/settings-1.0.0.xsd"> <servers> <server> <id>gvsig-repository</id> <username>nbrodin</username> <password></password> </server> </servers> </settings>
Desde una consola del sistema debemos tener definida la variable JAVA_HOME. Para ello escribimos:
export JAVA_HOME=$javasdk
donde $javasdk es nuestra ruta local al JSDK de java. Actualmente la versión utilizada es la 1.6.0
La instrucción de compilación desde dentro del proyecto libjni-xxxx es la siguiente:
mvn install -Dnative-arch=$arch -Dnative-distribution=$distri -Pjni-devel -Dmaven.test.skip
donde $arch puede tomar los valores “X86_64”, “i386”, “universal” y $distri puede ser “nt”, "all", “Ubuntu-9.10”, “10.5”, etc...
El flag -Pjni-devel forzará a compilar el código nativo.
Si el proceso se completa con éxito se generará:
- Un jar con las clases de java ya compiladas
- Un jar con los fuentes de java
- Un jar con los javadocs
- Un tar.gz con las librerías nativas compiladas
Los jar, tar.gz y fuentes se instalarán en el repositorio local de maven (.m2). Cuando estas dependencias sean necesitadas por una librería o extensión de gvSIG serán copiadas desde ahí.
El nombre del jar tendrá la forma siguiente:
“Estructura de paquete”-”versión”.extensión
Ej: org.gvsig.jgdal-2.0.jar
El nombre de los fuentes será:
“Estructura de paquete”-”versión”-sources.extensión
Ej: org.gvsig.jgdal-2.0-sources.jar
El de los javadoc:
“Estructura de paquete”-”versión”-javadoc.extensión
Ej: org.gvsig.jgdal-2.0-javadoc.jar
Y el de los binarios:
“Estructura de paquete”-”versión”-”operativo”-”distribución”-”compilador”-”plataforma”-dynamic/static.tar.gz
Ej: org.gvsig.jgdal-2.0-linux-all-gcc4-i386-dynamic.tar.gz
Las dependencias en tiempo de compilación con librerías del sistema se resolverán automáticamente si estas están debidamente instaladas. Por ejemplo para linux la compilación de jgdal necesita de la librería gdal instalada y se usará la del repositorio oficial de la distribución que usemos.
Para subir la versión que hemos compilado al repositorio habrá que hacer "deploy" del proyecto usando la siguiente instrucción:
mvn deploy -Dnative-arch=$arch -Dnative-distribution=$distri -Pjni-devel -Dmaven.test.skip
Los parámetros serán los mismos que usamos para hacer "mvn install"
Para compilar un proyecto nativo desde una consola en windows deberemos asegurarnos primero de que está definida la ruta al jdk de java en la variable PATH y que la variable JAVA_HOME también está definida.
Al abrir una consola de windows deberemos cargar el entorno de Microsoft Visual Studio. Para eso, habrá que ejecutar desde la consola el fichero llamado vcvars.bat, que está en el directorio bin de VC. La ruta más común para este fichero suele ser:
“C:Archivos de programaMicrosoft Visual Studio 8VCbin”
La compilación se hará con el comando:
mvn install -Pjni-devel -Dmaven.test.skip
Para subir la versión que hemos compilado al repositorio habrá que hacer "deploy" del proyecto usando la siguiente instrucción:
mvn deploy -Pjni-devel -Dmaven.test.skip
Los parámetros serán los mismos que usamos para hacer "mvn install"
La dependencias nativas (proyectos libjni-xxxx) son compiladas e instaladas en el repositorio local de maven ($HOME/.m2) usando “mvn install”, pero no son instaladas para ejecución a no ser que lo invoquemos explícitamente. Las dependencias nativas que se usan en la ejecución estarán en el directorio $HOME/.depman. En caso de linux el directorio lib contendrá las librerías y en caso de windows será el directorio bin. Para que esto suceda se ejecutará la instrucción:
mvn install -Pinstall-extension -Dmaven.test.skip
Esta instrucción se ejecutará dentro de la extensión que tenga dependencias con las librerías nativas, aunque sea de forma indirecta. Hay que tener en cuenta que las extensiones tienen un directorio distribution con un fichero distribution.xml con la información para regenerar las dependencias de las distribución en ejecución.
Dependencias externas (SDKs)
Las librerías que no están instaladas en el sistema necesitan ser resueltas para compilar. Para ello es necesario disponer del SDK de estas dependencias. El SDK de una dependencia contiene:
- Un directorio bin con las librerías dinámicas y ejecutables que tenga
- Un directorio data con ficheros de datos
- Un directorio include con las cabeceras para compilar
- Un directorio lib con librerías para compilación estática
El sdk estará empaquetado un tar.gz y el nombre tendrá la siguiente estructura:
“nombre de librería”-”version”-”operativo”-”distribución”-”compilador”-”plataforma”-dynamic/static.tar.gz
Ej: gdal-1.7.1-win-nt-vs8-i386-dynamic.tar.gz
A la hora de compilar una librería nativa es necesario que las dependencias estén instaladas en el directorio $HOME/.depman. Cuando se hace un maven install cogerá el tar.gz con el SDK del cual se depende y que está en el repositorio local (.m2) y lo descomprimirá en $HOME/.depman. En caso de que no esté instalado en el repositorio local se lo descargará del repositorio remoto. Este proceso se realizará de forma automática.
Cuando creamos un SDK del cual depende una librería nativa tendremos que subirlo al repositorio una vez montada la estructura que hemos definido en el apartado anterior. Para esto tendremos que empaquetar manualmente los ficheros en un tar.gz.
Una vez tenemos el paquete hecho habrá que subirlo al repositorio usando maven. La instrucción que debemos usar es similar a la siguiente:
mvn deploy:deploy-file -Dfile=”C:\gdal-1.7\gdal-1.7.1-win-nt-vs8-i386-dynamic.tar.gz” -Durl=scp://shell.forge.osor.eu/home/groups/gvsig-desktop/www/downloads/pub/projects/gvSIG-desktop/maven-repository -DrepositoryId=gvsig-repository -DgroupId=org.gdal -Dversion=1.7.1 -DartifactId=gdal -Dpackaging=tar.gz -Dclassifier=win-nt-vs8-i386-dynamic
En este caso se muestran valores de ejemplo para subir el SDK de gdal en su versión 1.7.1 en un windows de 32 bits con compilación con Visual Studio 8. Habría que sustituir estos valores por los correctos para nuestro caso.
El parámetro -DrepositoryId contiene una etiqueta que corresponde con el identificador que debe haber dentro del fichero settings.xml de nuestro directorio .m2. De esta forma podrá conectarse al repositorio por scp validando previamente la cuenta.
Dependencia de proyectos con librerías nativas
Es bastante común hacer uso de dependencias dentro de un proyecto tan grande como es gvSIG. Maven nos ayuda en la tarea de definir esas dependencias. En este apartado se explica como hacer que tu proyecto Java tenga como dependencia una librería nativa.
Únicamente es necesario modificar la sección <dependencies> de tu proyecto Java:
<dependency> <groupId>org.gvsig</groupId> <artifactId>org.gvsig.jgdal</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.gvsig</groupId> <artifactId>org.gvsig.jgdal</artifactId> <version>2.0</version> <classifier>${native-classifier}</classifier> <type>tar.gz</type> </dependency>
El ejemplo anterior lo que nos muestra es que se depende de la librería org.gvsig.jgdal, la primera parte se refiere a la parte Java de jgdal (los .jar), y la segunda parte se refiere a la parte nativa, es decir el conjunto de binarios dependientes de plataforma.
El elemento <classifier> de un pom, permite añadir un clasificador a cualquier artefacto maven, de manera que nos permite hacer un tratamiento especial. En el caso de las librerías nativas, el clasificador se ha utilizado para añadir la plataforma, arquitectura, distribución, sistema operativo y tipo de dependencia.
La propiedad ${native-clasifier} se genera a partir de otras propiedades, a continuación se muestra para cada sistema operativo soportado el valor que toma:
Linux:
<native-platform>linux</native-platform> <native-distribution>all</native-distribution> <native-compiler>gcc4</native-compiler> <native-arch>i386</native-arch> <native-libraryType>dynamic</native-libraryType>
Windows:
<native-platform>win</native-platform> <native-distribution>nt</native-distribution> <native-compiler>vs8</native-compiler> <native-arch>i386</native-arch> <native-libraryType>dynamic</native-libraryType>
MacOSX:
<native-platform>mac</native-platform> <native-distribution>10.5</native-distribution> <native-compiler>gcc4</native-compiler> <native-arch>universal</native-arch> <native-libraryType>dynamic</native-libraryType>
La propiedad se genera de la siguiente forma:
<native-classifier> ${native-platform}- ${native-distribution}- ${native-compiler}- ${native-arch}- ${native-libraryType} </native-classifier>
Por tanto es fácil cambiar cualquier valor desde la línea de comandos haciendo uso de -Dnative-distribution="valor que quiero que tenga".
Otro elemento que no es habitual en las dependencias de tipo jar, es el elemento <type/>. En este caso, se está usando para que la extensión de la dependencia que busque sea de tipo tar.gz, ya que en este caso al no ser un único fichero, si no un conjunto de binarios o incluso de ficheros necesarios para la compilación de librerías nativas, estos se empaquetan y comprimen en un archivo contenedor (tar.gz).
Al igual que maven tiene un repositorio local donde se descargan los jars de los que se depende, se ha creado un repositorio local donde se descomprimen los binarios nativos:
${user.home}/.depman
Donde en cada sistema operativo toma el valor adecuado. Los proyectos al descomprimirse generan una estructura de directorios similar al de un SDK de librerías nativas multiplataforma:
${user.home}/.depman/ |-include -- Cabeceras de archivos para C/C++ |-lib -- Nativos en linux/mac (.so/.dylib) o librerías de enlace en windows (.lib). |-bin -- Nativos en Windows (.dll). |-Frameworks -- Nativos en Mac (.framework)
Maven cuándo se descarga una dependencia nativa de tipo tar.gz, automáticamente la deposita en el repositorio de maven (${user.home}/.m2) sin descomprimir y a continuación la descomprime en el directorio ${user.home}/.depman. Además ese directorio se añade a los PATHS de ejecución de los Tests unitarios de librerías y proyectos Java, para que si requieren de la librería nativa no existan problemas de ejecución.
Creación/Migración de librerías Nativas a Maven
En este apartado se plantean las bases para la creación o migración de nuevas librerías nativas dentro de gvSIG. Primero se explica la estructura que deben seguir los proyectos para su correcta compilación y generación. A continuación cómo integrar el proyecto en CMake y cómo se debe generar el pom.xml para que todo el sistema compile de manera integrada en el sistema de construcción de gvSIG además de resumir el ciclo de vida de una librería nativa dentro del sistema de construcción de maven.
Para llevar a cabo un proyecto de una librería nativa, se recomienda una estructura de directorios determinada que facilitará la construcción y organización del proyecto:
librería-jni/ |-src/ |-main/ | |-java -- Ficheros .java | |-native -- Ficheros .cpp y de cabecera de C++ | |-resources -- Ficheros de recursos a incluir en el .jar |-test/ |-java -- Tests unitarios
Seguir esta estructura es importante, tanto para proyectos de maven, como para la compilación de la parte nativa, ya que CMake seguirá esta estructura para buscar los archivos fuente y generar los binarios nativos.
Aunque maven es capaz de compilar y administrar dependencias de tipo jar, no es así con las librerías nativas. Existe algún plugin que es capaz de ello, pero no al nivel que se requiere en un proyecto tan grande como gvSIG. Por ello se hace uso de CMake, que es un sistema para la construcción de librerías nativas multiplataforma (no únicamente librerías JNI).
CMake se encarga de generar los ficheros de proyecto y de compilación para cada plataforma y en cada sistema operativo, permitiendo manejar de una forma centralizada varios sistemas e incluso compiladores. Por ejemplo para linux generará los ficheros Makefile necesarios y para Windows generará los ficheros NMakefile o las soluciones de Visual Studio que se tenga instalada en el sistema.
Para facilitar la tarea se han incorporado al directorio build una serie de Macros de CMake que simplifican los ficheros de proyecto.
Para integrar una librería JNI con CMake es necesario crear en el directorio raíz un fichero CMakeLists.txt que tendrá la siguiente estructura:
PROJECT(jgdal) CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) SET(JGDAL_VERSION_MAJOR "2") SET(JGDAL_VERSION_MINOR "0") SET(JGDAL_VERSION_PATCH "0") SET(VERSION "${JGDAL_VERSION_MAJOR}.${JGDAL_VERSION_MINOR}.${JGDAL_VERSION_PATCH}") SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../build/CMakeModules;${CMAKE_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}") FIND_PACKAGE(DepMan REQUIRED) INCLUDE(GeneralMacros) CONFIGURE_DEFAULTS() IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) SET(CMAKE_INSTALL_PREFIX ${DEPMAN_PATH} CACHE PATH "depman path install prefix" FORCE ) ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) FIND_PACKAGE(JNI REQUIRED) FIND_PACKAGE(GDAL REQUIRED) ADD_SUBDIRECTORY(src/main/native) CONFIGURE_END()
El ejemplo anterior está basado en el de JGDAL y tiene varias instrucciones a tener en cuenta. La instrucción para la busqueda en el sistema de las librerías JNI necesarias para la compilación nativa es:
FIND_PACKAGE(JNI REQUIRED)
Para la búsqueda de otras dependencias que tu proyecto necesite se deberá hacer de una forma similar, por ejemplo en el caso de GDAL se hace:
FIND_PACKAGE(GDAL REQUIRED)
Aunque CMake incorpora una gran cantidad de scripts para la búsqueda de dependencias, si no tiene una, se pueden crear nuevas, como es el caso de GDAL, que se encuentra dentro del directorio CMakeModules ubicado en el directorio build.
Otra instrucción del script a tener en cuenta es la de:
ADD_SUBDIRECTORY(src/main/native)
Esta instrucción indica que se debe buscar archivos CMakeLists.txt en ese subdirectorio para configurar el resto de la compilación.
Hasta ahora sólo hemos configurado el entorno base de CMake, a continuación se muestra el script que debe ir dentro del directorio donde se encuentran los fuentes (.cpp,.c), para realizar la compilación del binario nativo:
SET(LIB_NAME jgdal) FILE(GLOB SOURCES "*.c*") include_directories( ${CMAKE_SOURCE_DIR}/include ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2} ${GDAL_INCLUDE_DIR} ) SET(LIBRARIES_OPTIMIZED ${GDAL_LIBRARY} ) SET(LIBRARIES_DEBUG ${GDAL_LIBRARY} ) SETUP_JNILIB(${LIB_NAME})
En este ejemplo, se están almacenando todos los ficheros .cpp y .c en la variable SOURCES y posteriormente se está configurando el entorno con los directorios de cabecera necesarios. Las variables JAVA_INCLUDE_PATH, JAVA_INCLUDE_PATH2 y GDAL_INCLUDE_DIR se definen al hacer uso de FIND_PACKAGE en el script principal, por lo que son accesibles para su uso en otros scripts. Luego se configuran las librerías de las que se depende, en este caso GDAL_LIBRARY. Finalmente se configura para que se cree una librería JNI.
Se recomienda que si se desea hacer un uso intensivo y avanzado de CMake se lea la documentación del mismo (http://www.cmake.org).
Para entender como se integra la construcción de librerías nativas en Maven es necesario entender como lleva a cabo la construcción maven, para ello primero exponemos lo que se denomina ciclo de vida de maven y a continuación mostraremos la configuración inicial.
Maven realiza ciertas fases denominadas ciclo de vida o lifecycle para llevar a cabo la compilación de los proyectos. En el caso de las librerías nativas, lo que se ha hecho es insertar ciertas acciones durante la ejecución de algunas de esas fases, aprovechando así el sistema de construcción que provee.
Los ciclos y lo que se realiza en cada uno de ellos se menciona a continuación:
- generate-sources: genera makefiles y busca dependencias nativas (target/target_cmake)
- compile: make install (target/target_cmake_product)
- package: genera tar.gz del producto compilado en target/
- install: instala el tar.gz en .m2/repository
- deploy: se instala en el repositorio remoto
El fichero de configuración pom.xml es similar a cualquier otro proyecto java, pero en este caso se configuran ciertos parámetros necesarios.
La cabecera se debe configurar de la siguiente manera:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.gvsig</groupId> <artifactId>org.gvsig.jgdal</artifactId> <packaging>jar</packaging> <version>2.0</version> <name>libjni-gdal Library</name> <parent> <groupId>org.gvsig</groupId> <artifactId>gvsig-base-library-jni-pom</artifactId> <version>2.0-SNAPSHOT</version> </parent> <properties> <build-dir>${basedir}/../build</build-dir> </properties> ...
No hay diferencia con otros proyectos, lo único a tener en cuenta es que la definición del elemento padre es: <artifactId>gvsig-base-library-jni-pom</artifactId>
El manejo de dependecias sigue siendo igual que en los proyectos java, aunque en las librerías nativas es habitual encontrarse que se depende de otras librerías nativas, por tanto se han de configurar correctamente, por ejemplo:
<dependencies> <dependency> <groupId>org.gdal</groupId> <artifactId>gdal</artifactId> <version>1.6.0</version> <classifier>${native-classifier}</classifier> <type>tar.gz</type> </dependency> </dependencies>
En algunos casos, nos podemos encontrar que una dependencia se pueda obtener por el sistema de paquetes del sistema (como es el caso de Ubuntu o Debian), por lo que no es necesario añadir la dependencia para ese sistema y sí para el resto, para ello se hace uso de los profiles de maven:
<profiles> <profile> <id>windows-profile</id> <activation> <property> <name>native-platform</name> <value>win</value> </property> </activation> <properties> <!-- This hack is necessary to allow correct search in windows --> <build-dir>${basedir}\..\build</build-dir> </properties> <dependencies> <dependency> <groupId>org.gdal</groupId> <artifactId>gdal</artifactId> <version>1.6.0</version> <classifier>${native-classifier}</classifier> <type>tar.gz</type> </dependency> </dependencies> </profile> <profile> <id>linux-profile</id> <activation> <property> <name>native-platform</name> <value>linux</value> </property> </activation> </profile> <profile> <id>mac-profile</id> <activation> <property> <name>native-platform</name> <value>mac</value> </property> </activation> <dependencies> <dependency> <groupId>org.gdal</groupId> <artifactId>gdal</artifactId> <version>1.6.0</version> <classifier>${native-classifier}</classifier> <type>tar.gz</type> </dependency> </dependencies> </profile> </profiles>
Con esta configuración y al incluir el pom padre específico para librerías jni, se incorporan a las fases del ciclo de vida la generación de los proyectos tipo makefile o NMakefile, la compilación, el empaquetado de los .tar.gz, la instalación en el repositorio de maven y por supuesto la instalación en el repositorio de librerías nativas ${user.home}/.depman y finalmente al hacer un deploy, el despliegue de esa dependencia.
Java ME CDC
cdc: compila un proyecto para Java ME CDC. Activa la compatibilidad con Java 1.4 y compila sobre el API de Java ME CDC. En algunos proyectos se emplea también para desactivar la compilación o generación de jars de partes no compatibles con Java ME CDC. Este perfil sólo se usa para el desarrollo en gvSIG Mobile. Ejemplo de uso:
mvn -P cdc install
Existen una serie de proyectos que mantienen compatibilidad, al menos a nivel de API, con Java ME CDC.
Para compilar (o cualquier otra acción) para Java ME CDC hay que activar un perfil de maven preparado para ello: cdc:
mvn -P cdc clean compile
Si se cambia entre compilación para Java SE y Java ME CDC, es recomendable limpiar la compilación para que no se empleen classes compiladas para el otro perfil, por eso se ha incluido la llamada al clean antes.
Problemas conocidos
No se encuentra la dependencia jre:javaws:jar:any
Se ha detectado que la versión del jdk 1.5 que se instala desde los repositorios en una Ubuntu de 64 bits (paquete sun-java5-bin) no instala el archivo javaws.jar, lo que provoca un error de dependencias al tratar de compilar el proyecto _fwAndami. Para solucionar esto hay que descargarse la versión del jdk 1.5 de 32 bits y copiar manualmente el jar al directorio correspondiente (${java.home}/lib/javaws.jar).
Este error también puede ocurrir si se está utilizando el OpenJDK, ya que parece ser que esta librería no está incluida. De momento gvSIG no soporta el OpenJDK, así que se puede copiar a mano la librería o bien usar el JVN de Sun.
Trabajando con un proyecto gvSIG
Compilar mi proyecto
Para compilar un proyecto desde maven, basta con invocar el objetivo:
mvn compile
Desde eclipse, se ha creado un lanzador en la opción de External Tools que permite compilar desde maven fácilmente, con el nombre: mvn compile.
Antes de usar este lanzador, deberemos seleccionar o estar editando algun archivo del proyecto que vamos a compilar, ya que se emplea la variable project_loc para invocar a maven sobre un proyecto.
Hay que tener en cuenta que el proyecto de eclipse está configurado de forma que las clases compiladas se generan en el mismo directorio que lo hace maven, así que, por lo general, al invocar este objetivo sobre un proyecto que tengamos abierto en eclipse, ya esté todo compilado y no haga nada.
Además de compilar, si queremos lanzar los tests unitarios de nuestro proyecto desde maven, emplearemos el objetivo:
mvn test
Finalmente, si queremos que el código que compilemos en un proyecto, esté disponible para otros proyectos que dependendan del mismo, deberemos generar el o los archivos .jar correspondientes, e instalarlos en el repositorio local de maven. Para ello emplearemos el objetivo:
mvn install
El objetivo install, además de compilar, lanza los tests unitarios del proyecto. Si queremos hacer la instalación sin lanzarlos, podemos usar el objetivo:
mvn install (no tests)
El equivalente desde consola es:
mvn -Dmaven.test.skip=true install
Los proyectos de gvSIG están configurados para generar, además del archivo .jar con las clases compiladas, otro archivo .jar con los fuentes. Esto nos será útil al enlazar las dependencias en maven y su uso desde los proyectos de eclipse.
Por otro lado, si queremos hacer una instalación y compilación desde cero, podemos usar el objetivo:
mvn clean install
Desplegar mi proyecto
Si nuestro proyecto es una extensión de gvSIG, existe una tarea adicional, además de la compilación y generación de archivos .jar: la instalación de la extensión sobre gvSIG.
Para ello se ha creado el siguiente perfil en maven:
install-extension: copia los archivos .jar generados, junto con el resto de recursos de la extensión (configuración, properties con textos multiidioma, imágenes, etc.) a gvSIG.
Dicho perfil está activado por defecto en los proyectos de tipo extensión, cuando invocamos al objetivo:
mvn install
Publicar mi proyecto
Una vez que hayamos terminado un determinado desarrollo en nuestro proyecto, y queramos que esté disponible para otros proyectos, sin que éstos tengan que descargar el código fuente de nuestro proyecto y compilarlo, podemos publicarlo en el repositorio de maven de gvSIG.
Este paso adicional se realiza a través del objetivo:
mvn deploy
Este objetivo realiza un mvn install y, a continuación, sube los artefactos generados, como el archivo .jar con las clases compiladas, al repositorio de maven.
Note
para que el deploy funcione deberemos tener un usuario con permisos en el proyecto gvSIG, y haber realizado correctamente la configuración definida en el documento Configuración inicial de maven (ver contenido relacionado al final del documento).
Los proyectos de gvSIG están configurados de forma que el repositorio al que se suben los artefactos es el de gvSIG.
Como se comenta en el apartado de compilación, en gvSIG se genera, por defecto, tanto el archivo .jar con las clases compiladas como el archivo .jar con el código fuente, que también se subirá al repositorio.
Además, si estamos publicando una versión con cambios significativos, será conveniente publicar también el javadoc en un archivo .jar. Para ello activaremos el perfil release con el siguiente objetivo desde eclipse:
mvn deploy release
Desde consola, el uso de maven directo es el siguiente:
mvn -P release deploy
TODO
Note
estudiar para el futuro el uso del maven release plugin
Generación de documentación e informes
Maven permite la generación de documentación a partir de los fuentes de un proyecto, como por ejemplo el javadoc.
Para ello existen una serie de plugins especiales de maven para la generación de informes.
Por ejemplo, para generar el javadoc usaremos el plugin correspondiente de la siguiente forma:
mvn javadoc:javadoc
Además de la generación de informes individuales, maven permite la generación de lo que llaman el site. Este consiste en un conjunto de páginas de informes de maven enlazadas, con un menú que nos permite navegar por todos los documentos generados.
De hecho, este mini website generado con maven es lo que emplean muchos de los proyectos Java de apache como website del proyecto.
Para los proyectos de gvSIG, se ha preconfigurado una serie de plugins con las opciones adecuadas del proyecto. Además, existen una serie de páginas que muestran información extraída del archivo pom.xml del proyecto, por lo que será importante completar y mantener actualizada dicha información.
En los proyectos que se generen usando los arquetipos de maven, el archivo pom.xml ya lleva los atributos necesarios predefinidos, a falta de rellenar y completar con valores reales.
Para generar el site invocaremos el objetivo:
mvn site
Esto nos generará la documentación dentro de nuestro proyecto, en la carpeta:
target/site
TODO
- Links javadoc, la variable site-repository y referencias entre proyectos.
- Publicación del site en el servidor público de gvSIG.
Cómo añadir o actualizar una dependencia
Si vamos a añadir o actualizar una dependencia externa en un pom.xml en un proyecto de gvSIG, tendremos que hacer lo siguiente:
Primero, nos asegurarnos que la dependencia y la versión que nos interesa está ya disponible en algunos de los repositorios oficiales de maven. Para ello tenemos dos opciones:
- Realizar una búsqueda manual, mediante google o inspección directa de alguno de los repositorios alternativos de maven.
Si hemos encontrado la dependencia deseada, ya podemos modificar el pom.xml, pues ya sabemos que está disponible para todos.
Si no hemos encontrado la dependencia, habría que pedir al proyecto original que suban la dependencia al repositorio oficial de maven, proporcionándoles la información necesaria para ello para que les sea más sencillo:
Así, contribuiremos con la comunidad a facilitar el uso de la librería correspondiente a través de maven. En algún proyecto es posible incluso que nos propongan que nos encarguemos de actualizar nosotros el repositorio de maven con nuevas versiones de una librería.
Si desde el proyecto original no se quiere hacer o se tarda mucho, podemos subirla temporalmente al repositorio maven de gvSIG, quitándola cuando esté disponible en el repositorio oficial.
¿Cómo subir una libraría al repositorio maven de gvSIG?
Lo ideal sería que todas las librerías de las que depende un proyecto de gvSIG tuviesen un repositorio maven para poder descargarlas. Lamentablemente esto siempre no es así y a veces hay que subir una librería al repositorio maven de gvSIG.
En ese caso, para hacer pruebas lo primero que debemos hacer es incluir la dependencia en nuestro repositorio local de maven. Para ello usaremos el siguiente comando:
mvn deploy:deploy-file -Durl=REPO_URL -DrepositoryId=some.id -Dfile=your-artifact-1.0.jar [-DpomFile=your-pom.xml] [-DgroupId=org.some.group] [-DartifactId=your-artifact] [-Dversion=1.0] [-Dpackaging=jar] [-Dclassifier=test] [-DgeneratePom=true] [-DgeneratePom.description="My Project Description"] [-DrepositoryLayout=legacy] [-DuniqueVersion=false]
El comando admite muchas opciones, sobre las cuáles podemos encontrar más documentación en la web del proyecto maven, en el apartado del plugin deploy. Sin embargo, lo más habitual será emplear lo siguiente:
mvn deploy:deploy-file -DgroupId=$LIBRARY_GROUPID -DartifactId=$LIBRARY_ID -Dversion=$LIBRARY_VERSION [-Dclassifier=$LIBRARY_CLASSIFIER] -Dpackaging=jar -Dfile=$LIBRARY_JAR -Durl=$REPOSITORY_URL -DrepositoryId=gvsig-repository
Los valores de las variables (empiezan por $) deberemos sustituirlos por:
- LIBRARY_GROUPID:
- un valor típico suele ser el dominio principal del proyecto. Por ejemplo, para los proyectos gvSIG es org.gvsig, para los proyectos apache org.apache, etc.
- LIBRARY_ID:
- identificador o nombre de la librería. Suele ser un nombre único o bien un nombre con estilo de paquete java. En gvSIG los proyectos emplean este último formato (ej: org.gvsig.tools.lib).
- LIBRARY_VERSION:
- versión del jar que vamos a subir.
- LIBRARY_CLASSIFIER:
- para proyectos que generan varios jars, se emplea este valor para distinguir entre ellos. Un valor típico es tests, para el jar con los tests unitarios del proyecto. Es opcional y no suele ser necesario.
- LIBRARY_JAR:
- path absoluto al archivo .jar que vamos a subir, o bien relativo desde el directorio donde ejecutamos maven
- REPOSITORY_URL:
url del repositorio maven al que vamos a subir. En general usaremos dos opciones:
El repositorio local de maven: $USER_HOME/.m2/repository.
En este caso hay que tener en cuenta que la dependencia sólo estará disponible para nuestro usuario en local. Suele emplearse para pruebas antes de subir la dependencia al repositorio de gvSIG.
El repositorio maven de gvSIG: dav:https://devel.gvsig.org/m2repo/j2se
Una vez subido a este repositorio ya estará disponible para el resto de desarrolladores.
Note
Para que el deploy funcione se ha tenido que configurar previamente el fichero settings.xml tal y como se indica en el documento "Configuración inicial de maven" de la guía del desarrollador, apartado "Acceso de escritura al repositorio maven de gvSIG".
A modo de ejemplo, supongamos que tenemos un jar de la librería JEP en su versión 2.4.0 que queremos incluir como dependencia. La instrucción completa a emplear sería:
mvn deploy:deploy-file -DgroupId=org.nfunk \ -DartifactId=jep \ -Dversion=2.4.0 \ -Dpackaging=jar \ -Dfile=jep.jar \ -Durl=dav:https://devel.gvsig.org/m2repo/j2se \ -DrepositoryId=gvsig-repository
How to create a gvSIG installer with installjammer
A quick howto prepared in the process of creating the gvSIG 2.0 installer using installjammer:
Download last final version of installjammer (http://www.installjammer.com/. While creating this document the last final version available was the 1.2.15 one, but it had a bug with link files, so we have used an hourly build of the 1.2 branch.
Run installjammer and click on the new installer icon.
Go through the wizard options filling the required information. Of special interest for gvSIG:
- Theme selection: Modern Wizard
- Platforms: Linux X86, Linux X86 64 and Windows. (tar and zip ones kill installjammer when building)
- Additional features: all checked but the "Allow users to select custom components in your install", as that will be managed through the gvSIG own installer.
Add files to install.
Create a file group for the common files non platform dependent, called gvSIG base. Add to it the product directory, checking everything but the platform dependent files and the plugins that won't be installed in the minimal installation.
Add to it also the $HOME/.depman/data folder to be copied to the root installation folder.
Create a file group for each supported platform (linux, windows, etc.). Add to them the product and $HOME/.depman/lib and bin folders and select only the files or folders of each platform
When you add a folder or file to a group, InstallJammer stores the absolute path. That would make a bit difficult to share the installer configuration. To solve it, Virtual Text variables can be used:
- Add a %BaseDir% Virtual Text variable pointing to your gvSIG installation. Then, for each product folder added in the file groups, edit the Location property and set it to <%BaseDir%>.
- Add three more variables to point to the data, lib and bin folders too, called:
- BaseNativeLibsDir: path to the $HOME/.depman folder.
- Lini386NativeLibsDir: path to the $HOME/.depman/lib folder.
- Wini386NativeLibsDir: path to the $HOME/.depman/bin folder.
Add license panel:
Open Install Panes and Actions > Standard Install
After the Welcome screen add a License agreement pane.
By default the license must be written in the configuration pane options. To read the license from a file, add a Execute script after the pane, with Execute action = Before pane is displayed and the tcl script:
set file [::InstallAPI::FindObjects -alias "ProgramLicense"] set file [$file srcfile] ::InstallAPI::SetVirtualText -virtualtext LicenseText -value [read_file $file]
The file with the license contents must be updated with the alias ProgramLicense. Go to Groups and files, look for the license file LICENSE.txt and into the properties update the Alias field.
Find java executable while installing:
- Create an action group called Find Java Actions, with the same name in its alias property (very important or it won't be shown when called from a pane action).
- Add a Locate Java Runtime action to the group and set the Minimum Version property to 1.5.
- Add a Message Box action to the group to be shown when the java executable is not found. Set the properties:
- Icon: error
- VirtualTextField: JavaNotFound
- Message: <%JavaNotFound%>
- Add a condition of type String is Condition with the properties: - Operator: false - String: <%JavaFound%>
- Add a Exit action to the group to exit the installer after the previous message box is shown if the java executable is not found. Set properties:
- Exit code: -1
- Add a condition of type String is Condition with the properties: - Operator: false - String: <%JavaFound%>
- Add a Execute Action to the Welcome Screen pane with the properties:
- Alias: Find Java
- Action: Find Java Actions
Replace variables in the gvSIG linux launcher (gvSIG.sh):
Add a Replace Text In File action into the Copying files pane, just after the Install Everything one.
Configure the added action with the properties:
Files: gvSIG.sh
String Map:
"JAVA_HOME=${JAVA_HOME}" "JAVA_HOME='<%JavaHome%>'" "GVSIG_HOME=`pwd`" "GVSIG_HOME='<%InstallDir%>'"
Launch the gvSIG add-ons installer before the installation process end:
Add a Custom Text Pane 1. To internationalize the text properties, save the project and look for the stored values in the .mpi file. It will be something like:
54A9E67A-F932-CDD4-6F9A-8842AAE31ACC,Title
Add the properties to be translated to the msg files located in build/projects/gvsig-standard/gvsig-standard-installer/src/main/installjammer
Add a new Action group called Install addons actions, with the same value for the Alias property.
Add to the group an action to launch the Addons manager in linux (or other non windows OS), using a Execute External Program action with the properties:
- Alias: Launch addons manager not windows
- Console title: <%AppName%> add-ons manager
- Program command line: <%ProgramExecutable%> --install --installURL=http://gvsig-desktop.forge.osor.eu/gvSIG-desktop/dists/<%Version%>/packages.gvspki language=<%Language%>
- Working Directory: <%InstallDir%>
- Add a condition of type Platform Condition so it is launched only in non windows OSs, with the properties: - Operator: is not - Platform: Windows
Add to the group an action to launch the Addons manager in windows, using a Execute External Program action with the properties:
- Alias: Launch addons manager windows
- Console title: <%AppName%> add-ons manager
- Program command line: <%InstallDir%>/gvsig-package-installer.exe --install --installURL=http://gvsig-desktop.forge.osor.eu/gvSIG-desktop/dists/<%Version%>/packages.gvspki language=<%Language%>
- Working Directory: <%InstallDir%>
- Add a condition of type Platform Condition so it is launched only in windows, with the properties: - Operator: is - Platform: Windows
Add a Execute Action to the Welcome Screen pane with the properties:
- Alias: Install addons
- Execute action: before next pane is displayed
- Action: Install addons actions
Add support to show the README contents in Spanish of English. By default installjammer configures the project to show the contents of only one file. To add this support is easy:
- Add a README panel with the Spanish contents by creating a copy (Copy and then Paste) of the View Readme Window action into the Finish actions group. Rename it to View Leeme Window and set the properties:
- Text File: <%InstallDir%>/LEEME.txt
- Add a condition so it only runs in Spanish, of type String Match Condition with the properties:
- Match Case: No
- Operator: matches
- Pattern: es*
- String: <%Language%>
- Change the File Exists Condition property:
- Filename: <%InstallDir%>/LEEME.txt
- Add a condition to the View Readme Window action so it only runs in non Spanish languages, of type String Match Condition with the properties:
- Match Case: No
- Operator: does not match
- Pattern: es*
- String: <%Language%>
- Add a README panel with the Spanish contents by creating a copy (Copy and then Paste) of the View Readme Window action into the Finish actions group. Rename it to View Leeme Window and set the properties:
gvSIG install build preparation steps
Prerequisites
You have to install the application used to create gvSIG installers in your computer: InstallJammer.
Go to http://www.installjammer.com and download the last final available version. The last version tested in the project has been the 1.2.15, but it had a bug in the installation of links (needed for native libraries), so the last 1.2 hourly build with that bug solved has been used.
Once installed, get sure the installjammer application (the installjammer executable itself, not a link) is available in your execution PATH.
Install build preparation steps
If necessary, update value of the package.info.state parameter in the paramers section of the pom.xml files of each plugin.
Update your workspace projects and clean, compile and install everything (mvn clean + mvn install). All external projects (org.gvsig.maven.base, org.gvsig.tools, etc.) must have been deployed in their last version previosly.
Launch gvSIG and perform a quick test.
Install the JRE plugin from jre_6_windows_i586 from the addons nanager.
Just in case you have created a previous build and you still have the generated add-on packages, remove everything into your build/product/install folder.
The gvSIG launchers for windows are still not generated automatically, so you should regenerate them with the Launch4J tool. Open the xml files located in build/projects/gvsig-standard/gvsig-standard-installer/src/main/launch4j with the Launch4J utility, update version and build numbers and regenerate the .exe files.
In case there have changes (new files in fwAndami, libCorePlugin or any other change in the online installer content) use the InstallJammer application to check that all the necessary files are included.
Generate the gvSIG installer and all the plugins add-ons: launch the goal mvn-create-installer from the build.xml of the gvsig-standard project available into build/projects/gvsig-standard.
Once the process is finished, you will have the following artifacts:
- gvSIG installers in: build/projects/gvsig-standard/gvsig-standard-installer/target/installjammer/output
- add-on packages in: build/product/install/pool
If there is an error while the process is generating the installers (at the end of the process), take a look at the InstallJammer configuration maintenance section.
From the command line, define the following environment variables:
USER=[downloads.gvsig.org user] BUILD_NUMBER=2043
Upload the installers to downloads.gvsig.org: copy the installers to /srv/download/gvsig-desktop/dists/2.0.0/builds/$BUILD_NUMBER/. Ex:
ssh $USER@downloads.gvsig.org "cd /srv/download/gvsig-desktop/dists/2.0.0/builds; mkdir $BUILD_NUMBER" scp build/projects/gvsig-standard/gvsig-standard-installer/target/installjammer/output/* \ $USER@downloads.gvsig.org:/srv/download/gvsig-desktop/dists/2.0.0/builds/$BUILD_NUMBER/
Generate if needed the add-on packages of plugins not included into the gvsig-standard project group, like:
- CRS
- Raster
- Geoprocessing
- Thematic Maps
- Etc...
Upload the add-on packages to /srv/download/gvsig-desktop/pool. Ex:
tar cvzfC upload.tar.gz build/product/install/ pool scp upload.tar.gz $USER@downloads.gvsig.org:/srv/download/gvsig-desktop ssh $USER@downloads.gvsig.org "cd /srv/download/gvsig-desktop; tar xvzf upload.tar.gz; rm upload.tar.gz"
Create the distribution for the build. Replace STATE and BUILD_NUMBER by the values of the distribution.
ssh $USER@downloads.gvsig.org "cd /srv/download/gvsig-desktop/dists/2.0.0; ../gvspkg mkdist --state STATE --build BUILD_NUMBER"
Install and perform a quick test of the generated installers, downloading all add-ons and checking some basic functionalities (linux, windows, ...).
If everything is OK, commit all changes in the buildNumber.properties files of each project. Else, solve any found problems and return to the first step.
Create a tag of the files included into the install build, with the build number in the tag name. Take into account that some of the project will be located in other svn repositories. You will have to create a tag into each of them, appart from the one in the gvsig-desktop project repository [1].
To create the tag, if you use the subclipse eclipse plugin, follow those steps (should be very similar if you use subversive instead):
- Select in your package explorer, project explorer or navigator, the projects to create the tag with.
- Click over them with the right button and select the option Team > Branch/Tag...
- In the Copy to URL: field put the URL to the tag to create. Ex: https://devel.gvsig.org/svn/gvsig-desktop/tags/v2_0_0_Build_2043. Check also the Create any intermediary folders that are missing and Preserve folder structure. The last one will put the projects into the tag with the same structure as the main branch (frameworks/_fwandami, libraries/libCompat, etc.).
- In the Create copy in the repository from: select the Working copy option. This way the tag will be created from the files you have into your workspace, so the tag won¡t contain any changes commited by other people while you where performing the build process.
- In the tag comment, put something about the build being created, like: gvSIG 2.0.0 build 2043.
Sadly, the subversion server might sometimes cut the connection so the tag process may stop in the middle. In that case, you will have some of the projects already available in the tag.
As the process follows the order of the projects in your package or project explorer, look in the svn log for the project where the error was produced, deselect the projects (already tagged) in your package/project explorer view listed before that project and start again with the previous steps.
Refresh the plone download page cache:
Create the notice ticket in the gvsig-desktop project tracker.
Note
TODO
Perform a deploy of the projects included into the build, through the mvn-deploy-release (this is the same as the mvn-deploy one, but also generates and uploads the javadocs jar files) command in gvsig-standard.
Only if there are changes in the API or other important changes generate or update the project's maven sites. As the command is still not available in the gvsig-standard ant configuration, you must call it from the command line: mvn site-deploy.
One way would be to launch the mvn site-deploy goal into the gvsig-standard-project, but the maven site plugin knows about multimodule projects, and it would try to create a main site also for the gvsig-standard-project, which could take forever to finish.
Another way to do it is to use some script to launch the mvn site-deploy goal for each project. You need to have mvn available into your execution path. As an example, into your workspace folder, launch the following command:
for i in lib* org* _fwAndami app* ext*; do cd $i; mvn site-deploy; cd ..; done
[1] | That last sentence will change when those external projects generate add-on packages by itselfs. |
JCRS
The JCRS related projects are not included anymore in the gvsig-standard build process.
As it has few changes and depends on native libraries, the packages for each platform will have to be created when there are changes in the CRS projects.
If you want to compile or create installers of the JCRS plugin, use the gvsig-jcrs group available into build/projects. With that group you will be able to work with all the CRS related projects at once: checking out, compiling, generating package installers, ....
The natives are selected depending on two things:
- The values configured into the $HOME/.gvsig.platform.properties file. Look for available values in the Maven initial configuration document.
- Your current platform, which activates a profile on each project with native dependencies selecting the required version of them, as may be different for each platform.
Taking this into account, how can you get all native dependencies for the supported platforms? There are two ways to do it:
Manually: change the $HOME/.gvsig.platform.properties once for each platform and compile each project with native dependencies deactivating your platform profile and activating the one desired:
mvn -P linux-profile,\!windows-profile compile
Take into account that if you launch the previous command in the console, the $HOME/.gvsig.platform.properties file is read on each login shell. Another way to change the platform properties for maven is to set them in the MAVEN_OPTS environment variable:
export MAVEN_OPTS='-Xmx384M -XX:MaxPermSize=64m -Dnative-classifier=linux-all-gcc4-i386-dynamic'
Automatically: use the script build/projects/gvsig-jcrs/prepare-all-platforms.sh, which will perform all required steps in the JNI projects.
InstallJammer configuration maintenance
Launch installjammer
Once installed, you can open the InstallJammer GUI by running the installjammer executable. As the gvSIG installer configuration uses variables to point to the local paths, you must run installjammer like this:
installjammer -DBaseDir [PATH_TO_GVSIG] \ -DBaseNativeLibsDir $HOME/.depman \ -DLini386NativeLibsDir $HOME/.depman/lib \ -DWini386NativeLibsDir $HOME/.depman/bin \ -DInstallVersion 2.0.0.2025 \ -DVersion 2.0.0 \ --
Deleted or new files and folders
InstallJammer, by default, includes all the new files available in the folders to include in the installation, but fails if any of the previous available files is not available anymore.
That might be useful most of the times, so if you add a file you don't need to update the installjammer configuration. Also if you forgot to install a file or folder, it fails so you can correct it.
But there are times when you want that explicit change:
- Delete a file or change it with another one with another name (ex: a new library version). If this is the case you must open the InstallJammer gui and remove the old file in the Groups and Files section.
- There is a new file or folder you don't want to be included by default. For example, when a new plugin is added, as the gvSIG/extensiones is added to the installation with some plugins to be included, the new one would be included too. You must open the InstallJammer gui and uncheck the new file or folder in the Groups and Files section.
Plugins de gvSIG incluidos en el InstallJammer
En el instalable que se genera con el el InstallJammer se deberan incluir los siguientes plugins de gvSIG:
- org.gvsig.coreplugin
- org.gvsig.installer.app.extension
Modificación del lanzador de la aplicación para windows
Puede ser necesario modificar de alguna manera el lanzador de la aplicacion para windows gvsig-desktop.exe para lo cual se deben seguir los siguientes pasos:
- Descargar la aplicación launch4j de http://launch4j.sourceforge.net/
- Descomprimirlo y ejecutarlo.
- Abrir el archivo /build/projects/gvsig-standard/gvsig-standard-installer/src/main/launch4j/gvsig.xml
- En la pestaña Basic se deben cambiar las rutas absolutas que figuran en los campos Output file, Jar e Icon por las que correspondan con nuestro workspace. Concretamente:
- Output file debe apuntar a nuestro_workspace/build/product/gvsig-desktop.exe
- Jar debe apuntar al jar de andami en nuestro_workspace/build/product/lib/org.gvsig.andami-2.0-SNAPSHOT.jar
- Icon debe apuntar a nuestro_workspace/build/product/gvSIG.ico
- En la pestaña Classpath se debe tener seleccionado el checkbox Custom classpath, en el campo Main class debe figurar org.gvsig.andami.Launcher y en el Classpath únicamente el jar de andami ./lib/org.gvsig.andami-2.0-SNAPSHOT.jar
- En la pestaña Header en Header type se debe seleccionar la opción GUI.
- En la pestaña Single instance no debemos seleccionar nada para que se puedan tener múltiples instancias de la aplicación ejecutándose al mismo tiempo.
- En la pestaña Version Info se pueden cambiar los campos File version, Free form, File description, Product version y, de nuevo, Free form pero esta vez de la sección Additional information, por lo que corresponda a la versión y número de build que vamos a generar.
- Hacer el resto de modificaciones que necesitemos.
- Salvar la configuración.
- Generar el ejecutable pulsando el icono con forma de engranaje Build wrapper.
- Si todo ha ido bien, este proceso habrá dejado el archivo gvsig-desktop.exe en la ruta que habíamos seleccionado en Output file.
- En algún momento de la instalación de la aplicación, se lanza también el instalador de complementos de gvSIG para lo cual generamos otro ejecutable gvsig-package-installer.exe. Para modificar dicho ejecutable podemos repetir estos mismos pasos teniendo en cuenta que:
- el archivo de configuración que debemos abrir es /build/projects/gvsig-standard/gvsig-standard-installer/src/main/launch4j/gvsig_package_installer.xml y
- que el Output file debe ser nuestro_workspace/build/product/gvsig-package-installer.exe
Official version publishing of gvSIG
To publish an official version of gvSIG Desktop in www.gvsig.org, the following steps must be followed:
- Rename the binaries with the following nomenclature:
- gvSIG-[major-number]_[minor-number]_[revision-number]-[Build-Number]-[final_pilot_alpha_RCx_prot]-[operat_syst-3_letters]-[Processor_Type]-[JVM_description]-[JVM].[file_extension].
For example: gvSIG-1_9-1245-final-lin-i586-withjre-j1_6.bin, gvSIG-1_9-1264-RC2-win-i586-j1_5.bin
- Rename source code files (if it's a file) with the following nomenclature:
- gvSIG-[major-number]_[minor-number]_[revision-number]-[Build-Number]-[final_pilot_alpha_RCx_prot]-[operat_syst]-src.[file_extension].
For example: gvSIG-1_9-1265-final-lin-src.zip
- Upload binaries and source code to OSOR.eu:
- In the Forge of the project, being logged, go to Files (for example in gvSIG Desktop: http://forge.osor.eu/frs/?group_id=89)
- In every project, 2 Packages will be created: one for stable versions and another one for unstable ones, for example: gvsig-desktop (final ver.), gvsig-desktop (other ver.), gvsig-network-ext. (final v.), gvsig-mobile (final v.)...
- In the corresponding Package, the Release must be created. For example:
For example: gvSIG 1.9 RC2 - Every file will be uploaded to this release.
- Upload the manuals to OSOR.eu:
- They will be renamed like this:
- gvSIG-[major-number]_[minor-number]_[revision-number]-man-[manual_version]-[language_2_letters].[file_extension]
For example: gvSIG-1_1-man-v1-en.pdf
- gvSIG-[major-number]_[minor-number]_[revision-number]-man-[manual_version]-[language_2_letters].[file_extension]
- In the Forge of the project, being logged, go to Files (for example in gvSIG Desktop: http://forge.osor.eu/frs/?group_id=89):
- A "Releases" folder must be created (if it doesn't exist)
- Inside that folder, a new folder called as the name of the version, with 2 figures (eg: 0.3) must be created
- Inside that folder, a new folder called as the name of the version, with 3 figures (eg: 0.3.0) must be created
- Manuals in pdf format will be uploaded to this last folder.
Official version publishing of gvSIG Mobile
To publish an official version of gvSIG Mobile in www.gvsig.org, the following steps must be followed:
- Rename the binaries with the following nomenclature:
- gvSIG_Mobile-[gvSIG_Mobile_version]-[Status]-[operat_syst]-[Processor_Type]-[JVM_description].[file_extension].
For example: gvSIG_Mobile-1_0-final-WMX-forPhoneME.cab, gvSIG_Mobile-0_3-Pilot-WMX-forPhoneME.cab, gvSIG_Mobile-0_3-RC2-WMX-forPhoneME.cab
- Rename source code files (if it's a file) with the following nomenclature:
- gvSIG_Mobile-[gvSIG_Mobile_version]-[Status]-src.[file_extension].
For example: gvSIG_Mobile-1_0-final-src.zip, gvSIG_Mobile-0_3-Pilot-src.zip
- gvSIG_Mobile-[gvSIG_Mobile_version]-[Status]-src.[file_extension].
- Upload binaries and source code to OSOR.eu:
- In the Forge of the project, being logged, go to Files (for example in gvSIG Mobile: http://forge.osor.eu/frs/?group_id=214)
- In every project, 2 Packages will be created: one for final versions and another one for versions on development, for example: gvsig-mobile (final ver.), gvsig-mobile (other ver.).
- In the corresponding Package, the Release must be created. For example:
- gvSIG Mobile 0.3 Pilot
- Every file will be uploaded to this release.
- Upload the manuals to OSOR.eu:
- They will be renamed like this:
- gvSIG_Mobile-[gvSIG_Mobile_version]-[Status]-man-[manual_version]-[language_2_letters].[file_extension]
For example: gvSIG_Mobile-0_3-Pilot-man-v1-en.pdf
- gvSIG_Mobile-[gvSIG_Mobile_version]-[Status]-man-[manual_version]-[language_2_letters].[file_extension]
- In the Forge of the project, being logged, go to Files (for example in gvSIG Mobile: https://forge.osor.eu/docman/?group_id=214):
- A "Releases" folder must be created (if it doesn't exist)
- Inside that folder, a new folder called as the name of the version, with 2 figures (eg: 0.3) must be created
- Inside that folder, a new folder called as the name of the version, with 3 figures (eg: 0.3.0) must be created
- Manuals in pdf format will be uploaded to this last folder.
Coding and Development Standards
Coding conventions
Forewords
This document describes a list of coding conventions that are required for code submissions to the project. By default, the coding conventions for most Open Source Projects should follow the existing coding conventions in the code that you are working on. For example, if the bracket is on the same line as the if statement, then you should write all your code to have that convention.
If you commit code that does not follow these conventions and you are caught, you are responsible for also fixing your own code.
Below is a list of coding conventions that are specific to gvSIG, everything else not specificially mentioned here should follow the official Sun Java Coding Conventions
Why code conventions
As explained in the Sun Java Coding Conventions:
Code conventions are important to programmers for a number of reasons:
- 80% of the lifetime cost of a piece of software goes to maintenance.
- Hardly any software is maintained for its whole life by the original author.
- Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.
- If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.
How to apply?
Having coding conventions is nice but having a way to ensure they are applied is even better ... :-)
The gvSIG maven configuration has a checkstyle target which performs coding conventions using the Checkstyle tool.
Please run this target before committing any code.
Also the eclipse configuration needed to format the source code taking into account the code conventions defined in the current document will be available in the org.gvsig.maven.base.build project, from the gvsig-tools OSOR project.
If the project you are working with has a prepare-workspace.xml file which you have used to configure your workspace, you will have those files already downloaded and available into the folder:
WORKSPACE/org.gvsig.maven.base.build/eclipse-configs
Otherwise, you may download all the files through the repository URL:
To import those configurations perform the following:
- Clean up:
- Go to Window > Preferences > Java > Code Style > Clean Up and click the button Import.
- In the file system explorer, select the clean_up.xml file.
- Code templates:
- Go to Window > Preferences > Java > Code Style > Code Templates and click the button Import.
- In the file system explorer, select the code_templates.xml file.
- Activate the option Automatically add comments for new methods and types.
- Formatter:
- Go to Window > Preferences > Java > Code Style > Formatter and click the button Import.
- In the file system explorer, select the formatter.xml file.
- Organize imports:
- Go to Window > Preferences > Java > Code Style > Organize Imports and click the button Import.
- In the file system explorer, select the organize_imports.importorder file.
gvSIG specific coding conventions
Mandatory conventions
Headers
Look at the Headers document for more information.
Indentations
4 spaces. NO tabs.
Javadoc
All API interfaces and classes must be fully documented through javadocs comments at interface/class, method and package level.
When you inherit or extend from another interface or class which is already documented, and implement or rewrite one of the parent methods, don't write any javadoc comments, as they are also inherited since java 1.4.
Brackets
All brackets should begin at the end of the line that begins the statement, and end on a new line indented to the beginning of the statement. Example:
AVOID:
public class MyClass { public void someMethod() { if (...) { // Do something } } }
RIGHT:
public class MyClass { public void someMethod() { if (...) { // Do something } } }
Brackets are mandatory even for single line statements:
if (expression) // AVOID! // some code if (expression) { // RIGHT // some code }
Blank Spaces
Keywords followed by a parenthesis should be separated by a space. Example:
while (true) { // some code }
Blank space should appear after commas in argument lists. Binary operators should be separated from their operands by spaces:
a += c + d; a = (a + b) / (c * d); while (d++ = s++) { n++; } printSize("size is " + foo + "\n");
Class variables
Class variables should not have any prefix or suffix related to its data type or scope. Example:
String nameString; // AVOID! String name; // RIGHT
Parameter names
Method parameters should be prefixed by "the" for differentiating them from inner variables, when there is an inner variable with the same name or use. For example:
public void someMethod(String theClassName) { String className; // inner variable }
Line length
Avoid lines longer than 80 characters for Code, comments, ...
Versioning
All .java files should have a @version tag like the one below into the class javadoc comment:
@version $Id$
Logging
Do not use System.out to log. Instead, use the SLF4J logging API. For example:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class); public void someMethod() { LOG.debug("some debug text"); }
For more information on SLF4J usage, you can read the Logging document.
Exception handling
Managing exceptions correctly requires experience. This is not supposed to be a guide on managing exceptions, simply a few best practices.
- Rule 1: Try to catch exceptions as much as possible and rethrow higher level exceptions (meaning hiding the low level detailed and putting a message that is more related to the function of your code).
- Rule 2: It is important not to loose the stack trace which contains important information. Use chained exceptions for that.
- Rule 3: Always log the exception at the higher level (ie. where it is handled and not rethrown).
- Rule 4: Try to avoid catching Throwable or Exception and catch specific exceptions instead.
- Rule 5: Create one parent Exception for each API library, so methods of the API that throw any exception use that parent exception or one of the child ones.
- Rule 6: If you have an exception or an error which can't be handled or resolved by code, throw or rethrow a BaseRuntimeException subclass.
An example:
public void getTestClass() { try { Class responseClass = Class.forName("some.package.MyClass"); } catch (ClassNotFoundException cnfe) { String message = "Cannot instantiate test class"; LOG.error(message, ex); throw new ChainedRuntimeException(message, e); } }
Qualified imports
All import statements should containing the full class name of classes to import and should not use the "*" notation: An example:
// AVOID! import java.util.*; import java.net.*; // RIGHT import java.util.Date; import java.net.HttpURLConnection;
Use interfaces in the declaration of methods and variables.
By example, if you need a variable x that is a list, declare it as List instead an ArrayList:
// AVOID! ArrayList x = new ArrayList(); HashMap y = new HashMap(); public HashMap create(ArrayList keys, ArrarList values) { ... } // RIGHT List x = new ArrayList(); Map y = new HashMap(); public Map create(List keys, List values) { ... }
API packages
Usually, API interfaces and classes will belong to the library's main root package. If you create subpackages, use them to group by functionality, not by type.
How to name packages
All packages must begin with org.gvsig.
For more information on this convention, you can read the How to name packages document.
Advised conventions
- How to name interfaces and classes
Attention!
TODO
For more information on this convention, you can read the How to name interfaces and classes document.
Nomenclature for classes and interfaces
Introduction
This document defines rules for naming classes and interfaces that allow a common style for gvSIG components to be maintained.
The importance of consistency in naming is obvious if one considers a complete Javadoc implementation. From the point of view of the reader, using a variety of naming conventions would create confusion and complicate the understanding of the component.
Criteria to follow
Use of prefixes and suffixes in general
The use of prefixes and/or suffixes in the names of classes and interfaces is usually a means of providing information about their nature and/or task. For example they can be used to denote a pattern, or a role within a pattern (eg the suffix Factory). At other times, it is necessary to use them if the appropriate name has already been assigned. This is the case of the prefixes and suffixes that are described below.
As a general rule:
- Only use a prefix or suffix when you can't use the simple name (usually because it is being used by another class or interface).
Using the prefix "Abstract"
- Only to be used for classes, not interfaces.
- The class must be abstract and implement an interface.
- Only used when the interface being implemented has the same name.
Example:
public interface List {} public abstract class AbstractList extends AbstractCollection implements List {}
Using the prefix "I"
It is recommended that this prefix not be used.
Typically, the interfaces are the visible part of a component model. They usually represent entities and concepts from the business or domain and therefore it is recommended that the same names be used as in the business.
Using the prefix "Default"
- Can't be an abstract class.
- A default implementation of an interface or an abstract class.
- The implementation should be sufficient, but not necessarily complete.
- There may be alternative implementations of this class.
Example:
public interface ListModel {} public abstract class AbstractListModel implements ListModel, Serializable {} public class DefaultListModel extends AbstractListModel {}
Using the prefix "Base"
- Not an abstract class.
- Provides a "base" implementation of an interface or an abstract class.
- The class can be instantiated and not used any more, but is designed for the user of the extended component.
- Do not use this prefix if no interface or parent abstract class exists.
Example:
public abstract class StreamRequestHandler {} public class BaseHTTPRequestHandler extends StreamRequestHandler {}
Using the suffix "Impl"
- It is a class instance and therefore can't be abstract
- It is a complete implementation of an interface or abstract class, generally referred to as the class without the "impl".
- Other classes should not be extended from it.
- Do not use this suffix unless the class name conflicts with the name of the interface or abstract class being implemented.
- If this is the default implementation of part of the API and does not conflict with other parts of the project, the prefix Default is preferred.
Example:
public interface Plane {} public abstract class AbstractPlane implements Plane {} // Both are correct (but not equal) public class PlaneImpl implements Plane {} public class PlaneImpl extends AbstractPlane {}
Application Conditions
This criterion is applicable to new developments undertaken for gvSIG 2.0 and will be part of the official gvSIG distribution as well as for all developments financed in whole or in part by the CIT.
Names of packages used in gvSIG
Preliminary considerations
Due to the variability and lack of unity in the names of packages used in gvSIG 1.X, it has been decided to standardize these, thereby giving the project an identity that over-rides that of the company doing the development.
Criteria to follow
When creating java packages that will be part of an official gvSIG release, or that will carry the official endorsement of the gvSIG project, the following package is appended:
org.gvsig
No mention is made in the package of the company doing the development.
Normally, the package name org.gvsig is followed by a package name identifying the logical or functional block that it contains.
Application Conditions
These criteria will be applied to new developments to be made to gvSIG 2.0, and will be part of the official gvSIG distribution as well as for all developments financed in whole or in part by the CIT.
Logging
In gvSIG the SLF4J library is used as a logging API.
The Simple Logging Facade SLF4J is a framework that is designed to abstract the underlying logging system. As Log4j is the most popular logging system in use, the framework's API is very similar to simply removing the direct dependence of this system. This framework is therefore an abstraction layer of the logging system and will allow us to change the underlying components without having to undertake major recoding of the application.
Features of SLF4J
- SLF4J is an abstraction layer independent of any actual logging system.
- Allows the end user to attach the desired implementation at deployment time.
- Allows gradual migration from Jakarta Commons Logging (JCL), because it has a JCL API wrapper in its own API.
- There is a parameterized logging system that reduces the overhead of assessing the message strings, especially when debug messages are enabled.
// Those lines produce the same results. The second one has parameters that reduce the overhead when debugging is disabled
LOG.debug("The new entry is "+entry+".");
LOG.debug("The new entry is {}.", entry);
- Support for Mapped Diagnostic Context (MDC), if the logging system operating under SLF4J supports it. At the moment only Log4j and logback do so.
- Logging systems may choose to implement the SLF4J interface directly as logback and SimpleLogger, or write SLF4J adapters for a given implementation as in the cases of Log4jLoggerAdapter and JDK14LoggerAdapter.
- Does not delegate to a specific class loading system (class loader) for delegating to a specific logging system, ie statically configured at compile time, only allowed to use one and only one logging system. Simply add the logging system API's jar to the CLASSPATH, together with slf4j-api.jar. This avoids the problems of class loading and memory loss suffered by Jakarta JCL.
- SLF4J also has an interface very similar to the JCL and Log4j APIs currently in use, so the implementation effort is significantly reduced.
- gvSIG continues to use the same logging toolkit (Log4j) so there will be practically no changes at run time.
- You gain in flexibility, robustness and efficiency through the ability to change the logging component without modifying the gvSIG source code, either for all versions of gvSIG or for specific versions.
- It's the standard that has been collected in OSGI projects because projects that are already using commons-logging can be adapted easily due to the popularity that this framework has gained.
Using SLF4J in gvSIG
gvSIG 2.0 is ready to work with SLF4J, using LOG4J as implementation, and can be used directly from any gvSIG extension.
To use SLF4J from a Java class just include the following statements:
1.- Import the necessary classes:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
2.- Declare and initialize the Logger:
public class MyClass
{
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
...
3.- We use the Logger within the code of the class when we want to display a log message, depending on the type: error, warning, information, debug or trace:
LOG.warn(String message);
LOG.warn(String message,Object arg1);
LOG.warn(String message,Object[] arg1);
LOG.warn(String message, Throwable arg1);
LOG.info(String message);
LOG.info(String message,Object arg1);
LOG.info(String message,Object[] arg1);
LOG.info(String message, Throwable arg1);
LOG.error(String message);
LOG.error(String message,Object arg1);
LOG.error(String message,Object[] arg1);
LOG.error(String message, Throwable arg1);
LOG.debug(String message);
LOG.debug(String message,Object arg1);
LOG.debug(String message,Object[] arg1);
LOG.debug(String message, Throwable arg1);
LOG.trace(String message);
LOG.trace(String message,Object arg1);
LOG.trace(String message,Object[] arg1);
LOG.trace(String message, Throwable arg1);
The following methods are provided to check the activation of messages for each level:
LOG.isErrorEnabled();
LOG.isWarnEnabled();
LOG.isInfoEnabled();
LOG.isDebugEnabled();
LOG.isTraceEnabled();
In addition, the messages can also be customized in SLF4J by inserting variables into the String of the log message, as in the following example:
private Integer temperature;
public void setTemperature(Integer temperature) {
LOG.debug("Setting temperature to {}. Old temperature was {}.", temperature, this.temperature);
this.temperature = temperature;
if(temperature.intValue() > 50) {
LOG.info("Temperature has risen above 50 degrees.");
}
}
This stops us from having to concatenate Strings, which reduces the cost of using the instructions for logging. This is because, although the log level that we are using is disabled (for example, debug), the method call will be made anyway, including the concatenation of strings to build the message, if any.
However, if the obtaining of any of the parameters to be passed to the message log proves costly, it is convenient to use the consultation methods to avoid such implementation. For example:
private Integer temperature;
public void setTemperature(Integer temperature) {
LOG.debug("Setting temperature to {}. Old temperature was {}.", temperature, this.temperature);
this.temperature = temperature;
addToTemperatureLog(temperature);
if (LOG.isDebugEnabled()) {
LOG.debug("The current average temperature is {} Celsius", calculateAverageTemperature());
}
}
Headers
Migrating Projects to gvSIG 2.0
Introduction
The following sections describe some of the main issues to consider when migrating a project (library or extension) from gvSIG 1.9 to gvSIG 2.0. These instructions will be largely applicable to projects being migrated from earlier versions as well.
Project name
A new project nomenclature should be defined, which should coincide with the main java package of the project, with the base names for jars that are generated or, also, with the artifactID of the maven project.
An example of this nomenclature would be:
extQuickInfo -> org.gvsig.quickinfo
Migrating to maven and the new project structure
gvSIG 2.0 has been migrated from ant to maven as a tool for constructing projects. Therefore, the ant build.xml file should be replaced with a maven pom.xml file.
Documentation on the pom.xml file format, as well as general maven documentation, can be found on the maven project website.
There is also a brief introduction and description of how to use maven in the gvSIG 2.0 development guide.
In addition, maven has a default project structure that allows the most common construction operations to be performed with a minimum of configuration. Adapting the project structure for migrating to the default maven structure is therefore quite convenient.
On the other hand, it is more convenient to create a new project from the maven templates or archetypes, and then to migrate the content from the old to the newly created project, rather than trying to convert the old project directory to the maven format.
These maven project templates (archetypes) allow us to create a simple project with everything needed to start working. There are many archetypes available:
If it is an internal project, use the create library or create extension archetype, according to the type of project required.
If the project to be migrated is an extension, then the correspondence between locations in the old and the maven directory is as follows:
- Sources: src -> src/main/java
- Source tests: src-test -> src/test/java
- Multilingual texts: config -> src/main/resources/locale
- config.xml: config -> src/main/resources/config
- Images: images -> src/main/resources/images
- about.htm: config -> src/main/resources/about
- build.number: [RAÍZ] -> src/main/resources
If this is an external project, follow the instructions in the document Creating our project to create the initial project structure.
Note
The external multi-module project archetype must still be created and documented.
Package nomenclature
Virtually all the code base of gvSIG projects has been migrated to the package nomenclature of org.gvsig.xxx.
When migrating a project, imports should be updated in the same class. Eclipse provides tools to easily make the necessary changes.
A quick way of doing this, for example, is in the package manager to select all classes in the project, right-click on them and then select Source > Organize Imports.
On the other hand, if the project being migrated belongs to the gvSIG project itself, the packages should be renamed to also begin with org.gvsig.
Logging
The logging API to use in gvSIG 2.0 is the SLF4J library. If the project being migrated is using another logging API, such as Log4J or java.util.logging, then it needs to be replaced with the SLF4J logging API. You can find more information on SLF4J in the section on logging in the development guide
In general, the steps needed to migrate from Log4J to SLF4J are:
1.- Replace the Log4J import classes with those of SLF4J:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// substituting the import of Log4j ...
// import org.apache.log4j.Logger;
2.- Change the Logger definition:
private static final Logger LOG = Logger.getLogger(MyClasser.class);
...
To:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
...
3.- Use message parameters where appropriate. For example:
LOG.debug("Point values: X = " + point.getX() + ", Y = " + point.getY());
...
To:
LOG.debug("Point values: X = {}, Y = {}", point.getX(), point.getY());
...
Moving to Java >= 1.5
gvSIG 2.0 supports Java version 1.5 or higher, except in joint projects with gvSIG mobile.
When migrating a project, we need to decide if we want the code to work on gvSIG mobile or not. If so, it is usually not all the code that needs to be compatible, only the library or the library API. It is therefore advisable to have these in a project separate from the rest and then to validate, unless the project compiles to Java ME CDC.
If the project does not need to be compatible with gvSIG mobile, or a part thereof, it is compiled with Java 1.5 or higher.
Due to the compilation with Java 1.5, it is advisable to remove the warnings that could appear in the code in Eclipse, such as the use of the classes of collections without the use of generics.
Dependencies
Dependencies in gvSIG 2.0 projects are managed from maven.
In addition to this change, there are a number of developments that affect how dependencies are defined in gvSIG:
- All dependencies are defined with their version.
- External dependencies are registered with their version in the pom.xml root configuration for all projects (see project org.gvsig.maven.base.pom). Therefore, a project only has to define its dependencies without indicating the version, as these have already been defined in the configuration project.
- All dependencies should be available in the official repositories of maven or osgeo. If not, they can be uploaded from the gvSIG repository.
- Dependencies with other gvSIG projects are defined in the same way as for any external project, indicating the groupId, artifactId and version.
- Some of the projects in gvSIG 2.0 have been divided in turn into other projects (for example, the libFMap project), so we must determine what our actual dependencies in gvSIG 2.0 are.
- Many projects begin to generate separate jars of their API, SPI, implementation, providers, etc. In general we rely solely on the API or SPI jars to build, and rely on the others only for performing tests.
Note
Every time dependencies are modified in the pom.xml file, the eclipse project has to be regenerated because the eclipse project configuration needs to be updated with said dependencies.
You can find more information about the management of dependencies in the section How to add or update a dependency in the gvSIG 2.0. development guide.
Persistence
In gvSIG object persistence is used, amongst other things, to save the project, symbols, etc.
In gvSIG 2.0 a new API and persistence implementation has been developed. It is compatible with Java ME CDC for use in the gvSIG Mobile project and completely replaces the previous API.
Therefore, we have to migrate all uses of persistence in our project so that they use the new API, which is available in the org.gvsig.tools.persistence package of the org.gvsig.tools project.
For more information about using the new persistence API, you can consult the persistence development guide.
Based on experience gained from migrating projects to date, we recommend that when migrating a project you don't rely on persistence as implemented with the old API, as it is often closely linked to the conditions leading to the earlier persistence, assumed a lot more work, besides making assumptions about the flow of persistence.
Instead we recommend that the migration of persistence be addressed as if it were being implemented for the first time, looking only at the class to be persisted, and which of its attributes to persist.
With the new API it is much easier to persist objects, since most of the time the attributes of the classes can be persisted directly, without having to manage their conversion between object and String.
Cloning objects
In versions prior to gvSIG 2.0, a common practice when implementing object cloning was to use persistence. An object was persisted and then 'unpersisted' to obtain a copy.
However, in gvSIG 2.0 this method will probably not work, as the new persistence API takes control of object references to avoid duplicating objects already loaded on the system, and so you may not get the desired results.
To implement object cloning a new API has been defined in org.gvsig.tools, as well as a development guide that shows how to implement and use cloning.
Initialisation of Libraries
There is often the need for some kind of initialisation when loading library projects. Up until now, every project has carried out this initialization on their own using different mechanisms.
To standardise and unify the operation of all projects, a library initialization mechanism has been defined in gvSIG 2.0, for which there is a short development guide showing how to use it in our projects.
Extension points
Extension points have undergone two major changes in gvSIG 2.0:
- Changes to the API.
- Project change, will now be in the org.gvsig.tools project.
You can find more information in the developer documentation on extension points.
Fmap
Introduction
The old libFMap project was divided into a number of subprojects which provided the core functionality. These projects, in turn, generated various artefacts or .jar files, which also affect the dependencies that we will include in our projects.
The main projects that have emerged from the former FMap are:
- org.gvsig.fmap.geometry (libFMap_geometries)
- org.gvsig.fmap.dal (libFMap_dal)
- org.gvsig.fmap.dal.file (libFMap_dalfile)
- org.gvsig.fmap.dal.db (libFMap_daldb)
- org.gvsig.fmap.dal.index.spatial (libFMap_dalindex)
- org.gvsig.fmap.mapcontext (libFmap_mapcontext)
- org.gvsig.symbology
- org.gvsig.fmap.control (libFMap_controls)
The following section discusses some of the major changes in functionality.
Geometries
In gvSIG 2.0 a separate project for geometry libraries has been constructed. It has evolved from what was in previous libraries and provides a separation between the API, implementation and operations on geometries.
There is development documentation available on the library, where we can see major changes at the API level, and a description of the model geometry that defines the library.
One of the major changes is that classes such as FShape have disappeared, and will be substituted by the interfaces available in the geometry library, such as Geometry and GeometryManager.
For example, where constant shape types were used to define the FShape class, there are now two options:
- Using geometry operations, we can associate types and/or subtypes of geometries.
- Using constant types and subtypes that are defined in the Geometry.TYPES and Geometry.SUBTYPES interfaces. This option has a big problem, in that these types and subtypes do not cover all possibilities, but only those defined initially as defaults. From now on libraries or extensions can be registered on their own, so if you use this option, instead of registering operations, our functionality won't function properly with these other geometry types.
In any case, if we choose the latter option, then we have a table showing the equivalents between the types of shapes and types of geometries of the new library:
FShape | Geometry.TYPES |
NULL | NULL |
POINT | POINT |
LINE | CURVE |
POLYGON | SURFACE |
TEXT | TEXT |
MULTI | GEOMETRY |
MULTIPOINT | MULTIPOINT |
CIRCLE | CIRCLE |
ARC | ARC |
ELLIPSE | ELLIPSE |
Z | (*) |
(*) In the gvSIG 2.0 geometry library, any geometry may be 2D, 3D, 2DM, etc. This feature is managed through the subtype of a geometry (see Geometry.SUBTYPES for predefined subtypes), so there is no equivalent for this constant in Geometry.TYPES.
Data access
One of the main changes in the development of gvSIG 2.0 has been the replacement of all previous data access methods with a new API and implementation, namely the DAL (Data Access Library).
This API combines access to both tabular and geometric data, in addition to defining a common core API between vector and raster data.
For more information about using the API, as well as the development of data providers, consult the DAL development guide.
Mapcontext, symbology and labelling
All code related to Mapcontext, symbology and labelling has been moved to a separate project: org.gvsig.fmap.mapcontext (libFMap_mapcontext). Those parts relating directly to mapcontext, the viewport, layers, etc. have not changed much since the previous version, except for changes required to conform to the rest of gvSIG 2.0.
The main change has been to extract the symbology and labelling API, as this API and the rest of mapcontext are a joint project between gvSIG desktop and gvSIG mobile.
The implementation of symbology and labelling now has its own project: org.gvsig.symbology. This is the implementation that is used in gvSIG desktop; gvSIG mobile has developed its own implementation.
Therefore, when a project is migrated to gvSIG 2.0 it will be affected mainly by:
- The extraction of the symbology and labelling API. These APIs have hardly been modified. The main change is that there are now managers for obtaining, creating and registering symbols, legends and labelling strategies. The entry point for accessing these managers will be the MapContextLocator.
- The introduction of new symbols, legends and labelling strategies. We use the previous managers to register them.
- A few changes to the rest of mapcontext, especially those related to data access, and issues such as InfoByPoint.
- Renamed all the starting packages with:
- org.gvsig.fmap.mapcontext: main package of the org.gvsig.fmap.mapcontext project (libFMap_mapcontext).
- org.gvsig.symbology: main package of the symboloy and labelling implementation project org.gvsig.symbology.
At the moment the development guide doesn't have any documentation available on this development.
Mapcontrol
A new project has been created where all the code related to MapControl is located: org.gvsig.fmap.control (libFMap_controls). This project also contains other graphical controls that depend on the other FMAP APIs, such as DAL.
For example, swing components, used from the gvSIG document table, have been created to display Feature tables. But now it is very easy to create applications outside of gvSIG, or to include other use cases that aren't from the document table, that show Feature data in tabular form.
Apart from the general changes to packages, and the adaptation to the other changes, this project has a few changes affecting the API. Some examples are:
- Rename the addCombinedTool method to addCombinedBehavior
- ...
appgvSIG
TODO
Changes to the project API and documents:
- View -> IView
Installer
TODO
Recommendations
Use the org.gvsig.i18n API directly. That is, instead of:
String text = PluginServices.getText(this, "Coordinates");
Use:
String text = Messages.getText("Coordinates");
Maintain a separation between the API, SPI, implementation and providers.
FAQs
Where is MapControl's addMapTool method?
Version 1.9 had an addMapTool method in the MapControl class but Version 2.0 doesn't.
Where can it be found?
The addMapTool method has simply been renamed addBehavior.
What is equivalent to the FieldDescription class in version 2.0?
In version 1.9 the FieldDescription class was used to query the attributes of a field in a table.
How is this done now?
In version 2.0 all data access has changed. To query the attributes that describe a field in a table you have to make use of the FeatureAttributeDescriptor class.
A vector layer has a FeatureStore, which in turn has a defaultFeatureType, that defines the structure of the feature by means of the FeatureAttributeDescriptor.
What has happened to FLyrVect's getRecordset and getSource methods?
The getSource and getRecordset methods were used to access a layer's data.
What is used now?
In version 2.0 the vector layers have a getFeatureStore method that returns a FeatureStore and provides access to both spatial and alphanumeric data.
If you just want to get all the layer's features you can invoke the getFeatureSet method of FeatureStore.
Can't locate the View class?
Some parts of my Extension were cast to the View class in order to access the view window.
Where is this class now?
The View class has been renamed and should not be used for casting. If you do need it, it will probably be sufficient to cast the IView interface.
Where can I find the ViewPort's getAdjustedExtent method?
How can I find the extent of the view port?
There is no longer a getAdjustedExtent method.
There has been a systematic elimination of all the methods that worked with an Extent. These have been replaced by methods for managing an Envelope. Operations on the gvSIG extent treated it as a 2D rectangle, which, with the emergence of more complex geometries, is no longer correct.
The methods that used to work on an Extent now work with an Envelope, and so have been renamed.
The getAdjustedExtent method has now become getAdjustedEnvelope.
How can I convert a geometry to JTS?
I have code that works with geometries that follow the JTS model.
How can I convert a gvSIG Geometry to JTS format?
You can do this by invoking:
Geometry geom;
com.vividsolutions.jts.geom.Geometry jtsGeom;
jtsGeom = (com.vividsolutions.jts.geom.Geometry) geom.invokeOperation(ToJTS.CODE, null);
Can't find getModel in the View class?
I have a variable of type View and would like to access the getModel method. Where I can find it in 2.0?
The code in 1.x was something like:
IWindow window;
MapContext mapa = ((View) window).getModel().getMapContext()
The code in 2.0 is:
IWindow window;
MapContext mapa = ((IView) window).getViewDocument().getMapContext();
How do I get an extension point?
To get an extension point:
The code in 1.x was something like this:
ExtensionPoint pe;
String name;
pe = (ExtensionPoint) ExtensionPointsSingleton.getInstance().get(name);
In 2.0 the code is:
ExtensionPoint pe;
String name;
pe = ToolsLocator.getExtensionPointManager().get(name);
The createLayer method of the LayerFactory class is deprecated. How do I create a raster layer?
The createLayer method of the LayerFactory class is deprecated. How do I create a raster layer?
The code in 1.x was something like this:
String filename;
BaseView view;
FLayer newLayer = LayerFactory.createLayer(filename, "gvSIG Image Driver",new File(filename), view.getProjection());
In 2.0 the code is:
String filename;
IView view;
DataStoreParameters parameters = DALLocator.getDataManager().createStoreParameters(RasterStoreProvider.NAME);
parameters.setDynValue("filename", filename);
parameters.setDynValue("srs", view.getViewDocument().getMapContext().getProjection());
FLayer newLayer = MapContextLocator.getMapContextManager().createLayer(filename, parameters);
Annexures
Migration to the OSOR subversion repository
The gvSIG subversion repository was moved from its own server at the gvsig.org domain to a server hosted in OSOR during the week of April 12th 2010.
The easiest way is to do a checkout of the project again in a new workspace. However, if we have changes to upload, another option is to change the reference to the subversion server in our own workspace.
At first, we have two options for this:
From eclipse: (for lack of testing) we can use the option Team > Disconnect on a project, and then Team > Share project indicating the new URL to use.
From console: we can use the option of the subversion client svn switch --relocate OLD_URL NEW_URL folder. For example, to migrate the build project of the 2.0 (from the same build project), we'd use:
svn switch --relocate \ https://gvsig.org/svn/gvSIG/branches/v2_0_0_prep/build \ https://svn.forge.osor.eu/svn/gvsig-desktop/branches/v2_0_0_prep/build \ .
All of this, project by project. If we have a unix shell (we are on linux, mac, windows with the cygnus utilities, etc.) we can use the following instructions (including to create a script) to migrate a complete workspace of the gvSIG core:
# Andami svn switch --relocate \ https://gvsig.org/svn/gvSIG/branches/v2_0_0_prep/frameworks/_fwAndami \ https://svn.forge.osor.eu/svn/gvsig-desktop/branches/v2_0_0_prep/frameworks/_fwAndami \ _fwAndami # Root projects for project in build binaries org.gvsig.core.maven.dependencies; do svn switch --relocate https://gvsig.org/svn/gvSIG/branches/v2_0_0_prep/${project} \ https://svn.forge.osor.eu/svn/gvsig-desktop/branches/v2_0_0_prep/${project} \ ${project}; done # Applications for project in app*; do svn switch --relocate https://gvsig.org/svn/gvSIG/branches/v2_0_0_prep/applications/${project} \ https://svn.forge.osor.eu/svn/gvsig-desktop/branches/v2_0_0_prep/applications/${project} \ ${project}; done # Libraries for project in lib*; do svn switch --relocate https://gvsig.org/svn/gvSIG/branches/v2_0_0_prep/libraries/${project} \ https://svn.forge.osor.eu/svn/gvsig-desktop/branches/v2_0_0_prep/libraries/${project} \ ${project}; done # Extensions for project in ext* org.gvsig.symbology; do svn switch --relocate https://gvsig.org/svn/gvSIG/branches/v2_0_0_prep/extensions/${project} \ https://svn.forge.osor.eu/svn/gvsig-desktop/branches/v2_0_0_prep/extensions/${project} \ ${project}; done
Developing gvSIG 1.10+ projects with an eye on gvSIG 2.0
The differences between versions 1.X and 2.X are very important in some areas of the application. There are important changes relating to:
- Construction of the project having moved from ant to maven.
- Standardisation of java package names.
- Data access architecture. The entire data access section has been rewritten in gvSIG.
- Re-engineering of the geometry access libraries.
- Rewriting of the mechanisms used for writing and retrieving data from the files of a gvSIG project.
- Rewriting of the mechanisms used for persisting the user data associated with a plugin.
- Change of the logging mechanism being used, from log4j to slf4j.
- The mechanism for packaging and installing plugins for gvSIG.
- The introduction of mechanisms for maintaining a separation between the API and implementation in the gvSIG code.
- Separation of the logic from the user interface. This is mainly in the parts of the application that have to be rewritten. In the parts where rewriting isn't necessary it can remain as it was.
- A guide to the coding conventions to be followed in gvSIG code has been developed.
In the light of these changes, there is no simple answer to the question What needs to be taken into account when initiating a development in the 1.X line and then later migrating to the 2 line?
The first issue that arises is that compatibility can't be maintained. Upon further reflection, there are some recommendations that can be followed, some more difficult than others. Some of them are listed here and developers will have to decide on their applicability to their projects:
Never modify gvSIG source code. Although this may seem obvious, don't modify the gvSIG code, use it as is. There are extension points in gvSIG that allow you to click on many of the gvSIG features in order to customize them. For those features where this is not available tell us so that we can study them and provide a solution.
Work with a gvSIG installable, not with the source. This is more than just a recommendation. Don't embed the gvSIG source along with your development in its workspace. Rather create a separate workspace for your development when deploying your plugins in a gvSIG installation.
Use maven as a construction mechanism. There is a maven repository for gvSIG version 1.9. If you are able to prepare your project with maven then you should follow the multi-module structure recommended for the gvSIG 2 line.
This is not essential and can be quite difficult if you aren't familiar with maven, but if you intend migrating to the gvSIG 2 line it is worth working towards.
Keep the API implementation and the contributed features separate. Try to find a balance between a monolithic implementation and having several API and implementation libraries. Also try to ensure that dependencies between them are only through the API.
If you want to start making the separation between the API and implementation in the 1.X code, you can use the mechanisms implemented in the org.gvsig.tools library for the gvSIG 2 line as these also work in the 1.X line.
Keep the data access sections within the application's logic during implementation, and try as far as possible to keep track of those parts of the code that access data. When migrating to version 2.X these are the parts of the application that will have to be modified.
Keep the access to controlled geometries in the logic part of the development. Changes in the handling of geometries are important in the 2.X line.
Control and document which parts of the application are saved with the project. Data storage in the project has changed completely and you are now required to declare what will be stored in the project. It is therefore advisable to keep the data storage well-documented in order to faciliate the migration to 2.X projects.
Use the slf4j API as a logging mechanism on the log4j backend. You can find more information on this in the document on Logging.
Use the clonable interface. Use this interface when you have to clone objects and follow the java recommendations for doing so. Never use the project's persistence mechanisms for cloning an object. You can find more information on this in the document on cloning objects.
In general it is a good idea to read the sections on Creating a gvSIG project and Migrating projects to gvSIG 2.0 in the gvSIG 2.0 developers guide.
FAQs
Error al ejecutar mvn -P create-installer install
Al ejecutar la creación de un instalador, ya sea mediante la opción mvn create installer o mediante un comando similar a este desde la consola:
mvn -P create-installer install
es habitual encontrarse con un error que termina con líneas como estas:
[artifact:mvn] [INFO] Creating package of the package info: [artifact:mvn] [INFO] org.gvsig.installer.lib.impl.DefaultPackageInfo@11e8050 ( [artifact:mvn] code: org.gvsig.oracle [artifact:mvn] name: [artifact:mvn] description: [artifact:mvn] gvSIG-version: [artifact:mvn] version: 0.0.1-0 [artifact:mvn] buildNumber: 0 [artifact:mvn] operating-system: all [artifact:mvn] architecture: all [artifact:mvn] java-version: j1_5 [artifact:mvn] download-url: [artifact:mvn] state: devel [artifact:mvn] official: false [artifact:mvn] type: unknow [artifact:mvn] model-version: 1.0.1 [artifact:mvn] owner: [artifact:mvn] owner-url: [artifact:mvn] sources-url: [artifact:mvn] dependencies: [artifact:mvn] web-url: [artifact:mvn] categories: []) [artifact:mvn] [INFO] ------------------------------------------------------------------------ [artifact:mvn] [ERROR] FATAL ERROR [artifact:mvn] [INFO] ------------------------------------------------------------------------ [artifact:mvn] [INFO] null [artifact:mvn] [INFO] ------------------------------------------------------------------------ [artifact:mvn] [INFO] Trace [artifact:mvn] java.lang.NullPointerException [artifact:mvn] at java.util.Hashtable.put(Hashtable.java:394) [artifact:mvn] at java.util.Properties.setProperty(Properties.java:143) [artifact:mvn] at org.gvsig.installer.lib.impl.info.InstallerInfoFileWriter.write(InstallerInfoFileWriter.java:101) [artifact:mvn] at org.gvsig.installer.lib.impl.info.InstallerInfoFileWriter.write(InstallerInfoFileWriter.java:74) [artifact:mvn] at org.gvsig.installer.lib.impl.info.InstallerInfoFileWriter.write(InstallerInfoFileWriter.java:59) [artifact:mvn] at org.gvsig.installer.lib.impl.DefaultInstallerProviderServices.writePackageInfoFile(DefaultInstallerProviderServices.java:148) [artifact:mvn] at org.gvsig.installer.lib.impl.DefaultInstallerProviderServices.writePackageInfoForIndex(DefaultInstallerProviderServices.java:136) [artifact:mvn] at org.gvsig.installer.lib.impl.creation.DefaultMakePluginPackageService.writePackageInfoForIndex(DefaultMakePluginPackageService.java:221) [artifact:mvn] at org.gvsig.installer.maven.GeneratePluginPackageIndexMojo.createPackage(GeneratePluginPackageIndexMojo.java:83) [artifact:mvn] at org.gvsig.installer.maven.AbstractGeneratePackageMojo.execute(AbstractGeneratePackageMojo.java:167) [artifact:mvn] at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490) [artifact:mvn] at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694) [artifact:mvn] at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556) [artifact:mvn] at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535) [artifact:mvn] at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387) [artifact:mvn] at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348) [artifact:mvn] at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180) [artifact:mvn] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328) [artifact:mvn] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138) [artifact:mvn] at org.apache.maven.cli.MavenCli.main(MavenCli.java:362) [artifact:mvn] at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60) [artifact:mvn] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [artifact:mvn] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [artifact:mvn] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [artifact:mvn] at java.lang.reflect.Method.invoke(Method.java:597) [artifact:mvn] at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315) [artifact:mvn] at org.codehaus.classworlds.Launcher.launch(Launcher.java:255) [artifact:mvn] at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430) [artifact:mvn] at org.codehaus.classworlds.Launcher.main(Launcher.java:375) [artifact:mvn] [INFO] ------------------------------------------------------------------------ [artifact:mvn] [INFO] Total time: 11 seconds [artifact:mvn] [INFO] Finished at: Fri May 11 15:34:48 CEST 2012 [artifact:mvn] [INFO] Final Memory: 57M/137M [artifact:mvn] [INFO] ------------------------------------------------------------------------ BUILD FAILED C:\dev\ew\gv2\build\ant-tasks\maven-goals.xml:35: The following error occurred while executing this line: C:\dev\ew\gv2\build\ant-tasks\ant-tasks-config.xml:117: Java returned: 1
Esto suele ocurrir porque no se ha incluído una referencia al archivo package.info en distribution.xml. La solución consiste en añadir un párrafo similar a este en dicho archivo:
<assembly> ... <files> ... <file> <source>package.info</source> <outputDirectory>${extension.install.dir.name} </outputDirectory> </file> ... </files> ... </assembly>
Eclipse señala errores de dependencias tras montar el workspace completo
Tras seguir los pasos descritos en el documento Cómo montar un workspace de gvSIG para Eclipse para montar un workspace completo de gvSIG, puede ocurrir que Eclipse nos señale mediante iconos de error algún problema de dependencias entre los diferentes proyectos. Esto ocurre aunque los scripts de ANT (mvn-eclipse-eclipse, mvn-install, etc) funcionan correctamente.
La causa podría ser un problema de comunicación entre Maven y Eclipse, que impide actualizar correctamente las dependencias de los proyectos en Eclipse.
El método conocido para solucionar esto consiste en comprobar en la pestaña Problems, qué proyectos tienen ese problema y usar el método mvn eclipse individualmente sobre cada uno de ellos, hasta eliminar todos los mensajes de error.
Tras montar el workspace de gvSIG al intentar ejecutar gvSIG no encuentra el jar de andami.
Tras montar el workspace de gvSIG tal como se indica en el documento Cómo montar un workspace de gvSIG para Eclipse, si intentamos ejecutar gvSIG desde el launcher de Eclipse, nos presenta un error diciendo que no puede encontrar el fichero ".../build/product/lib/...andami...jar" .
Si el proceso de descarga del workspace de gvSIG a terminado de forma satisfactoria esto puede deberse a que en el fichero $HOME/.m2/settings.xml esta especificada la ruta en la que hay que desplegar los plugins de gvSIG a una carpeta distinta a la de build/product de dentro del workspace de gvSIG. Esto es facil que ocurra si antes de montar el worlspace de gvSIG hemos estado trabajando con una instalacion de gvSIG generando plugins con el asistente para la generacion de plugins, en cuyo caso tendremos en el settings.xml la ruta a esa instalacion.
Para solucionarlo podremos hacer dos cosas:
- Editar el fichero $HOME/.m2/settings.xml y eliminar el profile en el que se define la propiedad "gvsig.install.dir"
- Editar el fichero $HOME/.m2/settings.xml y sustituir la ruta sustituyendola por la de la carpeta build/product del workspace de gvSIG.
Si vamos a estar trabajando tanto con el workspace de gvSIG como con el de algun otro plugin que estemos desarrollando sera recomendable la ultima opcion.