Wiki » History » Version 36
Henning Blohm, 01.02.2015 20:41
1 | 1 | Henning Blohm | h1. Intro |
---|---|---|---|
2 | |||
3 | 2 | Henning Blohm | This project is for the development of [[z2-environment:wiki|z2-environment]] version 3.0. |
4 | 1 | Henning Blohm | |
5 | 2 | Henning Blohm | Version 3.0 is a major refactoring release of z2 with new repository code lines and complete package renaming. |
6 | 1 | Henning Blohm | |
7 | 36 | Henning Blohm | Check out the roadmap at "roadmap":https://redmine.z2-environment.net/versions/27 |
8 | |||
9 | 2 | Henning Blohm | h1. Essential Differences between v2.3 and v3. |
10 | 1 | Henning Blohm | |
11 | 2 | Henning Blohm | * All the typical declarations and package names are no longer *com.zfabrik.<something>* but rather *org.z2env.<something>* |
12 | 13 | Henning Blohm | * The <z2 home> layout is completely new and more flexible |
13 | 3 | Henning Blohm | * The essential component types that can be _invoked_ from the core is *system state* and *main program*. |
14 | 14 | Henning Blohm | * While Jetty is still contained to support Eclipsoid and z2Unit, we support a pre-installed Tomcat as application container (and with TomEE would even get a Java EE profile) |
15 | 1 | Henning Blohm | * The core is lighter and more dedicated. |
16 | 12 | Henning Blohm | * There will be substantially less built-in application support like |
17 | ** a local JTA implementation |
||
18 | ** No worker suppport without a corresponding add-on. |
||
19 | 1 | Henning Blohm | |
20 | 12 | Henning Blohm | The main task of v3 is: |
21 | 13 | Henning Blohm | * Make the lower parts of z2 more accessible and easier to understand: While z2 previously started System Centric, we now close the gap from the ordinary main program. |
22 | 12 | Henning Blohm | * Increase the OSS flavor of z2 |
23 | 15 | Henning Blohm | |
24 | Obvious TODOs: |
||
25 | * Test TomEE |
||
26 | * Fix Eclipsoid templates |
||
27 | * Support MVNCR, also for distributions |
||
28 | 12 | Henning Blohm | |
29 | 9 | Henning Blohm | h1. Draft Intro Documentation |
30 | 1 | Henning Blohm | |
31 | 2 | Henning Blohm | h2. Getting Started |
32 | 1 | Henning Blohm | |
33 | 2 | Henning Blohm | To understand how z2 works, you need to understand at most what are z2 modules and components and what are component repositories and how these concepts interplay. |
34 | 1 | Henning Blohm | |
35 | 6 | Henning Blohm | Check out [[wiki#Understanding-Z2|understanding-z2]] for that. |
36 | 1 | Henning Blohm | |
37 | 2 | Henning Blohm | It is simplest to start by running a simple Java main program in z2 or a simple Web App. |
38 | 1 | Henning Blohm | |
39 | 2 | Henning Blohm | Follow this trail: |
40 | 1 | Henning Blohm | |
41 | 4 | Henning Blohm | * [[wiki#Building-z2env-core|Building the core]] |
42 | 7 | Henning Blohm | * [[wiki#Running-a-Hello-World-main-program|Running a Hello World main program]] |
43 | 10 | Henning Blohm | * [[wiki#Running-a-Hello-World-Web-App|Running a Hello World Web App]] |
44 | 22 | Henning Blohm | * [[wiki#Developing-with-Eclipse-or-IntelliJ|Developing with Eclipse or IntelliJ]] |
45 | 32 | Henning Blohm | * [[wiki#Going-Multi-Module|Going Multi Module]] |
46 | 1 | Henning Blohm | |
47 | 22 | Henning Blohm | |
48 | |||
49 | 3 | Henning Blohm | h2. Building z2env-core |
50 | 1 | Henning Blohm | |
51 | 17 | Henning Blohm | (For now, we need to build the core). |
52 | |||
53 | h3. Pre-requisites |
||
54 | |||
55 | * You need Git installed |
||
56 | * You need a JDK, at least version 7 |
||
57 | * You need the ANT build tool |
||
58 | |||
59 | 3 | Henning Blohm | First clone http://git.z2-environment.net/z2env.core |
60 | |||
61 | <pre> |
||
62 | git clone http://git.z2-environment.net/z2env.core |
||
63 | </pre> |
||
64 | |||
65 | 25 | Henning Blohm | Change into *org.z2env.core.main* and run |
66 | 3 | Henning Blohm | |
67 | <pre> |
||
68 | 18 | Henning Blohm | ant -Doutput=<z2home> -Dsetup=<setup> |
69 | 3 | Henning Blohm | </pre> |
70 | |||
71 | 18 | Henning Blohm | where <z2home> is where you want to install z2 (the *z2 home* that is) and <setup> is a choice of pre-configured content, actually component repositories. |
72 | 3 | Henning Blohm | |
73 | If you omit *output* it will default to *gen/dist*. If you omit *setup*, no content will be pre-configured will be modified. |
||
74 | |||
75 | Check the folder *setups* for available setups of the core build. These can be local (all repos will be cloned locally) or remote (repos will be remoted). |
||
76 | |||
77 | 1 | Henning Blohm | In general this build always updates only boot, z.jar, roots. It will not remove anything. |
78 | |||
79 | 18 | Henning Blohm | |
80 | 3 | Henning Blohm | Example to install/update a core only into ../../z2env: |
81 | |||
82 | <pre> |
||
83 | 24 | Henning Blohm | ant -Doutput=../../z2env |
84 | 3 | Henning Blohm | </pre> |
85 | |||
86 | 1 | Henning Blohm | To install/update a web-basic setup (with tomcat and eclipsoid support) with updates from remote repos: |
87 | |||
88 | <pre> |
||
89 | 3 | Henning Blohm | ant -Doutput=../../z2env -Dsetup=web-basic-remote |
90 | </pre> |
||
91 | 19 | Henning Blohm | |
92 | Check out [[wiki#Understanding-the-ltHOMEgt|Understanding the <HOME>]] to learn more about the generated structure. |
||
93 | |||
94 | 7 | Henning Blohm | |
95 | h2. Running a Hello World main program |
||
96 | |||
97 | For now, we will assume you have a z2 core installed in <HOME>. In its purest form, all the core can actually execute is simple Java main programs. |
||
98 | |||
99 | Being in a modular environment, even if we only want to say „Hello World“, we need a module. Let's call it the greeter module. In order to have a main program run by z2, we need to also declare a component for it, as that is what we tell z2 to run (not a class – mind you – but rather a component in a module). Assuming we use the local component name hello, than the absolut component name is |
||
100 | |||
101 | <pre> |
||
102 | greeter/hello |
||
103 | </pre> |
||
104 | |||
105 | Finally, as this component actually has implementation code, we need to declare a Java component. By convention this is |
||
106 | |||
107 | <pre> |
||
108 | greeter/java |
||
109 | </pre> |
||
110 | |||
111 | Now, after installing in <HOME> the place to simply drop a module is under <HOME>/modules. All in all, here is the complete structure to create: |
||
112 | |||
113 | | <HOME>/modules/greeter/hello.properties | |
||
114 | <pre><code class="ruby">org.z2env.component.type=org.z2env.main |
||
115 | component.className=greetings.Main |
||
116 | </code></pre> | |
||
117 | | <HOME>/modules/greeter/java/z.properties | |
||
118 | <pre><code class="ruby">org.z2env.component.type=org.z2env.java |
||
119 | </code></pre> | |
||
120 | | <HOME>/modules/greeter/java/src.impl/greetings/Main.java | |
||
121 | <pre><code class="java"> |
||
122 | package greetings; |
||
123 | |||
124 | public class Main { |
||
125 | public static void main(String[] args) { |
||
126 | 8 | Henning Blohm | System.out.println("Hello!"); |
127 | 7 | Henning Blohm | } |
128 | } |
||
129 | </code></pre> | |
||
130 | |||
131 | That gives us the two components of module greeter. To run this on the command line, run |
||
132 | |||
133 | <pre> |
||
134 | java -DcomponentName=greeter/hello -jar z.jar |
||
135 | </pre> |
||
136 | |||
137 | 1 | Henning Blohm | Now, obviously this sample is not worth a modular execution environment. But even from here, you could check your module in with some Git repository that is referenced from the roots and all other users of the same repo would be able to run your component without installing anything. |
138 | 10 | Henning Blohm | |
139 | h2. Running a Hello World Web App |
||
140 | |||
141 | 11 | Henning Blohm | This introduction explains how to connect a z2 core to a given Tomcat installation and how to develop a simple Web Application. |
142 | 7 | Henning Blohm | |
143 | 11 | Henning Blohm | Furthermore it describes how to use the Dev Repository and the Eclipsoid plugin for the Eclipse or the IntelliJ development environment. |
144 | |||
145 | h3. Pre-Requisites |
||
146 | |||
147 | * We assume a development workspace in *workspace*. |
||
148 | * Have a local Tomcat (7 or higher) installation.* |
||
149 | |||
150 | h3. Steps we are going to take |
||
151 | |||
152 | # Create a module with a simple Web app |
||
153 | # Make it visible to Z2 |
||
154 | # Run the Web App in a Tomcat Web Container |
||
155 | |||
156 | At first get yourself a z2env core with the *web-basic-local* or *web-basic-remote* setup. Make sure it is in your *workspace*. If you follow [[wiki#Building-z2env-core|Building the core]] this means running |
||
157 | |||
158 | <pre> |
||
159 | ant -Doutput=workspace/z2env -Dsetup=web-basic-remote |
||
160 | </pre> |
||
161 | |||
162 | 26 | Henning Blohm | (*Note:* If in doubt, use an absolute path for *workspace*) |
163 | 1 | Henning Blohm | |
164 | 26 | Henning Blohm | Using your IDE create a new project *hello* in *workspace* with the following structure: |
165 | 11 | Henning Blohm | |
166 | | java/z.properties | |
||
167 | <pre><code class="ruby"> |
||
168 | org.z2env.component.type=org.z2env.java |
||
169 | java.privateReferences=\ |
||
170 | javax.servlet |
||
171 | </code></pre> | |
||
172 | | web/z.properties | |
||
173 | <pre><code class="ruby"> |
||
174 | org.z2env.component.type=org.z2env.tomcat.webapp |
||
175 | webapp.path=/hello |
||
176 | </code></pre> | |
||
177 | | web/WebContent/index.jsp | |
||
178 | <pre><code class="html"><html><body>Hello! Did you know that 7*7=<%=7*7%>?</body></html></code></pre> | |
||
179 | | LOCAL | <empty file> | |
||
180 | |||
181 | 20 | Henning Blohm | Your *workspace* folder now contains two subfolders *z2env* and *hello*. |
182 | |||
183 | 11 | Henning Blohm | So far, that's it. We will touch on the LOCAL file later. |
184 | |||
185 | When we run Z2 knowing this Web Application, it will attempt to start a Tomcat Web Container that will serve the application's content. To do that, it needs to find one. |
||
186 | |||
187 | In order to tell Z2 where to look, you can either set an environment variable *CATALINA_HOME* (you might have already – it's the Tomcat standard) or specify an environment variable *catalina.home*. |
||
188 | |||
189 | To be on the safe side and assuming the location is */home/me/tomcat*, we open a terminal, change into *workspace/z2env* and run |
||
190 | |||
191 | <pre> |
||
192 | java -Dcatalina.home=/home/me/tomcat -jar z.jar hello/web |
||
193 | </pre> |
||
194 | |||
195 | Note, unlike for the main program, the command line will not return. Instead you can enter „q“ to quit or „s“ to synchronize. But first let's open a browser and check out |
||
196 | |||
197 | <pre> |
||
198 | http://localhost:8080/hello |
||
199 | </pre> |
||
200 | |||
201 | 28 | Henning Blohm | *Note:* What you just created is a prototypical z2 module structure containing a Java component *java* (holding implementation) and a Web component *web*. |
202 | 1 | Henning Blohm | |
203 | 28 | Henning Blohm | Instead of creating the structure yourself, you could use the Eclipsoid plugin (introduced below) for that: |
204 | * In Eclipse: New / Others / new z2...., |
||
205 | * In IntelliJ: New / Module / z2.... |
||
206 | 1 | Henning Blohm | |
207 | 28 | Henning Blohm | ... but beware of the pre-generated configuration. Where it says *com.zfabrik* change to *org.z2env*. |
208 | 27 | Henning Blohm | |
209 | 28 | Henning Blohm | |
210 | *Note:* Now on to that LOCAL file. Unlike for the Hello World main program, this time it was to so-called Dev Repo that made our module available to z2. |
||
211 | 11 | Henning Blohm | |
212 | The dev repo is a key component to the development approach with z2. It checks for all modules that have a LOCAL file and that are stored some levels deep, relative to the parent folder of the z2 home (by default), which not so coincidentally is our workspace. |
||
213 | |||
214 | Try this: |
||
215 | |||
216 | # Remove LOCAL |
||
217 | # Enter „s“ for synchronization. |
||
218 | # Check the URL above (should say „not found“) |
||
219 | # Create a LOCAL file again |
||
220 | # Synchronize |
||
221 | # Check again. |
||
222 | 1 | Henning Blohm | |
223 | 11 | Henning Blohm | Similarly, from now on, changes made to the hello module will be picked up, whenever you synchronize. |
224 | 1 | Henning Blohm | |
225 | 22 | Henning Blohm | h2. Developing with Eclipse or IntelliJ |
226 | 1 | Henning Blohm | |
227 | 21 | Henning Blohm | In this section we will add some code to the hello Web app and see how to develop using an integrated development environment like the Eclipse IDE or Jetbrains' IntelliJ IDEA. |
228 | 1 | Henning Blohm | |
229 | 21 | Henning Blohm | h3. Pre-Requisite |
230 | 1 | Henning Blohm | |
231 | 21 | Henning Blohm | * Have an Eclipse or IntelliJ installation |
232 | * Install the Eclipsoid plugin from http://z2-environment.net/eclipsoid/update/site.xml or by searching for "z2" in the IntelliJ Plugin Repository respectively |
||
233 | |||
234 | h3. Steps we are going to take |
||
235 | |||
236 | # Complete the development workspace setup |
||
237 | # Add a simple Controller |
||
238 | |||
239 | h4. In Eclipse |
||
240 | |||
241 | Use the workspace *workspace*. Create a Java project *hello* where we created the *hello* module. That is, we use the existing module as project content. You should now have an Eclipse development workspace that has one Java project named "hello". Right-click on the project and choose "Transform into z2 Project". A small "Z" icon should not decorate the project icon. |
||
242 | |||
243 | 30 | Henning Blohm | Add a source folder *java/src.impl* to the project. |
244 | |||
245 | 21 | Henning Blohm | Try "Arm Z2 Projects" and "Disarm Z2 Projects" from the context menu. You should see a LOCAL file showing up and disappearing as well as the "Z" decoration showing a green halo and going back to normal. |
246 | |||
247 | Go into Window/Preferences, pick "z2-Environment". Change the port to 8081, set the user to "z*" and the password to "z". Done. |
||
248 | |||
249 | h4. In IntelliJ |
||
250 | |||
251 | 30 | Henning Blohm | Add a source folder *java/src.impl* to the module. |
252 | |||
253 | 21 | Henning Blohm | Start a new Project with root folder *workspace*. Press the "Manage z2-Modules" button in the toolbar. Import the *hello* module into your IntelliJ project. Open the Settings dialog, pick "z2-Environment". Change the port to 8081, set the user to "z*" and the password to "z". Done. |
254 | |||
255 | h4. IDE Indepently |
||
256 | |||
257 | Start z2 as in the previous section but make sure the development support is enabled. Use this command line: |
||
258 | |||
259 | <pre> |
||
260 | java -Dcatalina.home=/home/me/tomcat -jar z.jar org.z2env.dev.shared/ready hello/web |
||
261 | </pre> |
||
262 | |||
263 | (possibly you want to turn this into a shell script) |
||
264 | |||
265 | 23 | Henning Blohm | *Note:* The _system state_ *org.z2env.dev.shared/ready* will pull up all necessary development support components. Make sure this is part of your to-be-run list. |
266 | 1 | Henning Blohm | |
267 | 29 | Henning Blohm | |
268 | 1 | Henning Blohm | Regardless whether you are using Eclipse or IntelliJ, press the "Resolve Classpath from Z2" button in the toolbar. This will make sure that all required dependencies for Z2 modules, as far as Java code is concerned, will be resolved for your workspace. |
269 | 29 | Henning Blohm | |
270 | 30 | Henning Blohm | Now add a class *SimpleController* and change the following files: |
271 | 21 | Henning Blohm | |
272 | 22 | Henning Blohm | | java/src.impl/hello/SimpleController.java | |
273 | 21 | Henning Blohm | <pre><code class="java"> |
274 | package hello; |
||
275 | |||
276 | import javax.servlet.*; |
||
277 | import javax.servlet.http.*; |
||
278 | import java.io.IOException; |
||
279 | |||
280 | public class SimpleController extends HttpServlet { |
||
281 | |||
282 | @Override |
||
283 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
||
284 | String input = req.getParameter("input"); |
||
285 | if (input!=null && input.trim().length()>0) { |
||
286 | req.setAttribute("output","You said: "+input); |
||
287 | } |
||
288 | req.getRequestDispatcher("/").forward(req,resp); |
||
289 | } |
||
290 | } |
||
291 | </code></pre> | |
||
292 | | java/z.properties | |
||
293 | <pre><code class="ruby"> |
||
294 | org.z2env.component.type = org.z2env.java |
||
295 | |||
296 | java.privateReferences=\ |
||
297 | javax.servlet,\ |
||
298 | javax.servlet.jsp.jstl |
||
299 | </code></pre> | |
||
300 | | web/WebContent/WEB-INF/web.xml | |
||
301 | <pre><code class="xml"> |
||
302 | <?xml version="1.0" encoding="UTF-8"?> |
||
303 | <web-app id="hello" version="2.5" |
||
304 | xmlns="http://java.sun.com/xml/ns/javaee" |
||
305 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||
306 | xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> |
||
307 | |||
308 | <servlet> |
||
309 | <servlet-name>controller</servlet-name> |
||
310 | <servlet-class>hello.SimpleController</servlet-class> |
||
311 | </servlet> |
||
312 | |||
313 | <servlet-mapping> |
||
314 | <servlet-name>controller</servlet-name> |
||
315 | <url-pattern>/do</url-pattern> |
||
316 | </servlet-mapping> |
||
317 | </web-app> |
||
318 | </code></pre> | |
||
319 | | web/WebContent/index.jsp | |
||
320 | <pre><code class="html"> |
||
321 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core_1_1" %> |
||
322 | <html> |
||
323 | <body> |
||
324 | <c:if test="${not empty output}"> |
||
325 | <p><c:out value="${output}"/></p> |
||
326 | </c:if> |
||
327 | <form method="POST" action="<c:url value='/do'/>"> |
||
328 | Input: <input type="text" name="input"><input type="submit" value="go!"> |
||
329 | </form> |
||
330 | </body> |
||
331 | </html> |
||
332 | </code></pre>| |
||
333 | |||
334 | Make sure the *hello* module is armed (right-click) by having a LOCAL file. |
||
335 | |||
336 | Now synchronize your running z2 by either: |
||
337 | |||
338 | * Pressing the "Sync with z2-Environment" button in the toolbar |
||
339 | * Pressing ALT+y in your IDE |
||
340 | * Entering "s" on the command line running z2. |
||
341 | |||
342 | Go to http://localhost:8080/hello and check it out. |
||
343 | |||
344 | |||
345 | h2. Going Multi-Module |
||
346 | 12 | Henning Blohm | |
347 | 31 | Henning Blohm | In this section we will extend the previous work by a simple service module. |
348 | |||
349 | h3. Pre-Requisites |
||
350 | |||
351 | # Have all the results from the previous section ready. |
||
352 | # Start IDE and z2 as above. |
||
353 | |||
354 | |||
355 | h3. Steps we are going to take |
||
356 | |||
357 | # add a new module with a service API |
||
358 | # reference the module API from the *hello* module and invoke the service. |
||
359 | |||
360 | |||
361 | In your workspace, use Eclipsoid to create a new z2 Java module *goodbye*. Open *java/z.properties* and change all *com.zfabrik.* prefixes to *org.z2env*. Essentially the file only needs the line |
||
362 | |||
363 | <pre><code class="ruby"> |
||
364 | org.z2env.component.type=org.z2env.java |
||
365 | </code></pre> |
||
366 | |||
367 | In our API we will only expose an interface and rather leave the implementation hidden in the implementation parts of the module. We do that, as we prefer a strong separation of API and implementation. This is not at all required but a conscious design choice. |
||
368 | |||
369 | |||
370 | | java/src.api/goodbye/GoodbyeService.java | |
||
371 | <pre><code class="java"> |
||
372 | package goodbye; |
||
373 | |||
374 | public interface GoodbyeService { |
||
375 | |||
376 | String sayGoodbye(String in); |
||
377 | |||
378 | } |
||
379 | |||
380 | </code></pre> | |
||
381 | | java/src.impl/goodbye/GoodbyeServiceImpl.java | |
||
382 | <pre><code class="java"> |
||
383 | package goodbye; |
||
384 | |||
385 | public class GoodbyeServiceImpl implements GoodbyeService { |
||
386 | |||
387 | @Override |
||
388 | public String sayGoodbye(String in) { |
||
389 | return "Goodbye "+in+"!"; |
||
390 | } |
||
391 | |||
392 | } |
||
393 | </code></pre> | |
||
394 | | java/service.properties | |
||
395 | <pre><code class="ruby"> |
||
396 | org.z2env.component.type=org.z2env.any |
||
397 | component.className=goodbye.GoodbyeServiceImpl |
||
398 | </code></pre> | |
||
399 | | java/z.properties | |
||
400 | <pre><code class="ruby"> |
||
401 | org.z2env.component.type=org.z2env.java |
||
402 | </code></pre> | |
||
403 | 1 | Henning Blohm | |
404 | 32 | Henning Blohm | In effect we created the following: |
405 | |||
406 | * A module *goodbye* that has |
||
407 | * A Java component with API and Implementation source code |
||
408 | * An _any_ component *goodbye/service* that manages the service implementation (as we will see below) |
||
409 | |||
410 | Back in the *hello* module, we want to use the _goodbye service_. We apply the following changes: |
||
411 | |||
412 | | java/z.properties | |
||
413 | <pre><code class="ruby"> |
||
414 | org.z2env.component.type=org.z2env.java |
||
415 | |||
416 | java.privateReferences=\ |
||
417 | javax.servlet,\ |
||
418 | javax.servlet.jsp.jstl,\ |
||
419 | goodbye |
||
420 | </code></pre> | |
||
421 | 33 | Henning Blohm | | java/src.impl/hello/SimpleController.java | |
422 | 32 | Henning Blohm | <pre><code class="java"> |
423 | package hello; |
||
424 | |||
425 | import goodbye.GoodbyeService; |
||
426 | |||
427 | import java.io.IOException; |
||
428 | |||
429 | import javax.servlet.ServletException; |
||
430 | import javax.servlet.http.HttpServlet; |
||
431 | import javax.servlet.http.HttpServletRequest; |
||
432 | import javax.servlet.http.HttpServletResponse; |
||
433 | |||
434 | import org.z2env.components.IComponentsLookup; |
||
435 | |||
436 | public class SimpleController extends HttpServlet { |
||
437 | |||
438 | @Override |
||
439 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
||
440 | GoodbyeService gb = IComponentsLookup.CL.lookup("goodbye/service", GoodbyeService.class); |
||
441 | String input = req.getParameter("input"); |
||
442 | if (input!=null && input.trim().length()>0) { |
||
443 | req.setAttribute( |
||
444 | "output", |
||
445 | gb.sayGoodbye(input) |
||
446 | ); |
||
447 | } |
||
448 | req.getRequestDispatcher("/").forward(req,resp); |
||
449 | } |
||
450 | } |
||
451 | </code></pre> | |
||
452 | |||
453 | After you have changed the Java references in *java/z.properties* you might want to press Alt-R or the "Resolve Classpath from Z2" button in the toolbar to have the IDE resolve the dependency for the *goodbye* module and so that |
||
454 | your IDE will not complain about using the *GoodbyeService* interface. |
||
455 | |||
456 | Now synchronize your running z2 by either: |
||
457 | |||
458 | * Pressing the "Sync with z2-Environment" button in the toolbar |
||
459 | * Pressing ALT+y in your IDE |
||
460 | * Entering "s" on the command line running z2. |
||
461 | |||
462 | Go to http://localhost:8080/hello and check it out. |
||
463 | 31 | Henning Blohm | |
464 | 34 | Henning Blohm | h3. Discussion |
465 | 31 | Henning Blohm | |
466 | 34 | Henning Blohm | What you just implemented is a programmatic component lookup. The first time <code>IComponentsLookup.CL.lookup("goodbye/service", GoodbyeService.class)</code> was invoked, z2 searched for a factory for *org.z2env.any* components. This specific factory simply created a singleton instance of the Goodbye Service and checked whether the requested interface is implemented. As that held, it returned the actual instance. |
467 | |||
468 | In later sections (for now check out [[z2-environment:How_to_Spring]]) we will explain how to that extends to the Spring Framework and Dependency Injection in general. |
||
469 | 12 | Henning Blohm | |
470 | 35 | Henning Blohm | Feel free to apply changes to the Goodbye Service implementation class and have them made effective by synchronizing Z2. |
471 | |||
472 | 12 | Henning Blohm | h2. Going System-Centric |
473 | |||
474 | TBD |
||
475 | |||
476 | Getting more real by adding a remote repo as system repo. |
||
477 | |||
478 | Develop by checking out modules and using the Dev Repo. |
||
479 | 3 | Henning Blohm | |
480 | 1 | Henning Blohm | |
481 | 3 | Henning Blohm | h2. Understanding the <HOME> |
482 | 1 | Henning Blohm | |
483 | 18 | Henning Blohm | We call an installation of a z2env core a *<home>*. The file structure of the *<home>* consists of few but important locations |
484 | 3 | Henning Blohm | |
485 | 18 | Henning Blohm | h3. Layout |
486 | |||
487 | 3 | Henning Blohm | | z.jar | The actual core implementation. This is precompiled.| |
488 | | boot/ | A component repository adding to the core and provides the most basic capabilities such as compiling Java code and running a main program. | |
||
489 | | roots/ | A file system component repository that is always registered by the core. This is typically filled with other repository components linking to remote or local component repositories. | |
||
490 | 1 | Henning Blohm | | modules/ | A file system repository declared under roots/ that is useful to locally augment a core installation.| |
491 | |||
492 | We use the modules repository for example for command line experiments and simple hacks. It is not as useful for regular development operations as is the dev repo. |
||
493 | 18 | Henning Blohm | |
494 | h3. Folders and Properties |
||
495 | |||
496 | When running z2 from the command line, some logic is applied to derive where stuff is and some defaults apply: |
||
497 | |||
498 | |_. What |_. System property |_. Defaults | |
||
499 | | Z2 home - the installation location | org.z2env.home | If no system property is set, the environment variable Z2_HOME will be checked. If that is not set, the z2 home location will be derived from the location of the z.jar file | |
||
500 | | Dev Repo workspaces - where the Dev Repo checks for local modules | org.z2env.dev.local.workspaces | Defaults to ${z2.home}/.. assuming modules will be next to the home or one level deeper | |
||
501 | |||
502 | 5 | Henning Blohm | |
503 | h2. Understanding Z2 |
||
504 | |||
505 | Most of the concepts that make up z2 can be derived from the desire to efficiently develop standard Java Web Applications that are defined in a central system definition. Add to that the wish to avoid all that build complexity and the desire for a practically usable modularization approach. |
||
506 | |||
507 | Once you loose the ability to tweak some build script or configuration to describe how to package a Web app or some libraries, you need some structural hint and simple declarations providing sufficient information. |
||
508 | |||
509 | Secondy, assuming you want to apply changes at runtime, you need some way of determining what to unload at runtime, given some changed file. Again: Structural information needs to present that maps to runtime state. |
||
510 | |||
511 | Finally, as we want some support for modular application development anyway, why not make modules our essential structure. As we have not only code but also Web Applications, Data Sources, Background Jobs and much more to consider, we add components with type into the mix. Voila. |
||
512 | |||
513 | *Component Repositories* provides modules and components to z2. A component is prefixed by the module name: |
||
514 | |||
515 | <pre> |
||
516 | <global component name> = <module name>/<local component name> |
||
517 | </pre> |
||
518 | |||
519 | In fact, the typical component repository has a file system style structure that is made up exactly like that. |
||
520 | |||
521 | Structure from repo root: |
||
522 | |||
523 | | /<module>/<cmp>.properties | A component <cmp> in module <module> that has no resources on its own.| |
||
524 | | /<module>/<cmp>/z.properties | A component <cmp> in module <module> that may have additional resources on its own.| |
||
525 | |||
526 | Note that some components, like Web applications and typically Java components have file resources, such as HTML files or Java source code files, while other components, such as main program declarations or data source declarations, so not. |
||
527 | |||
528 | There are some conventions around this naming scheme. In particular, by convention, whenever a component requires Java implementation, z2 will first look for a component named *java* of the same module. As for example in the Hello World example. |
||
529 | |||
530 | To give you an idea what this model translates to at runtime consider this: At runtime, the static component is turned into a Resource instance by a component type implementation (that, in fact, is provided by another, built-in component type). |
||
531 | |||
532 | !uml1.png! |
||
533 | |||
534 | Dependencies, for example those between Java components, translate into dependencies between resources that are observed during invalidation of resources. This introduces invalidation and synchronization. |
||
535 | |||
536 | 16 | Henning Blohm | h3. A crucial concept of z2 is that of a synchronization. |
537 | 5 | Henning Blohm | |
538 | For fast development roundtrips and in some cases for general configuration updates, it is desirable to not require a complete restart of a Java Virtual Machine process but rather just to change runtime state accordingly. |
||
539 | |||
540 | In z2 a synchronization describes the following process: |
||
541 | |||
542 | # Check for changes in component repositories |
||
543 | # Based on changes found, identify components affected and invalidate associated runtime resources incl. dependent resources. |
||
544 | # Try to attain target states |
||
545 | |||
546 | 1 | Henning Blohm | That is, whenever you do a change and trigger a synchronization from your IDE, this is exactly what happens: Identify what needs to be thrown away, make sure to remove dependent stuff as well, bring up what needs to be running. |
547 | 16 | Henning Blohm | |
548 | h3. A second crucial concept of z2 is that of *System Centric Development* |
||
549 | |||
550 | When working on a software system with many access points and high re-use on a service level, as is typical for business systems, staying quick integration with a team's changes is key. Component repositories can be fed from remotely accessible version control systems such as Subversion and Git. When connecting to a central, team-shared repository, every synchronization will make sure that you are up-to-date with the real source of truth. |
||
551 | |||
552 | Using the dev repo, you can still isolate yourself from changes on part of the system that you are actively working on. After your modifications are completed, rebased, and locally tested, getting a clean and consistent state is just one synchronization away. |
||
553 | |||
554 | h3. The third and final concept is that of a compile-free environment |
||
555 | |||
556 | It is within the nature of the synchronization concept, that anything required to happen to have your software available for execution must have happened after synchronization completed. Most preparation steps are executed at first use. This includes the compilation of Java code. Z2 uses the Eclipse Java Compiler for that purpose. |
||
557 | 9 | Henning Blohm | |
558 | h2. The Component Model |
||
559 | |||
560 | See [[z2-environment:Z2_Modules_intro]] |
||
561 | |||
562 | h2. Java Components |
||
563 | |||
564 | See [[z2-environment:Z2_Java_components_intro]] |