-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlisting5.html
executable file
·638 lines (548 loc) · 29.4 KB
/
listing5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>JavaSplashScreen - /JavaAppLauncher.m</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/Java/index.html">Java</a> > <a href="../../samplecode/Java/idxPorting-date.html">Porting</a> > <A HREF="javascript:location.replace('index.html');">JavaSplashScreen</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<div style="width:100%; position:fixed;"><div align="center" id="watermark" style="position: relative; margin-left:auto; margin-right:auto; z-index:20; width:500px;"><div class="legacybox"><h1>Not Recommended Document<span class=closebutton><a href="javascript:closeWatermark()"><img src="../../images/closebutton.png" width="14" height="14" border="0" alt="close button"></a></span></h1>
<p><strong>Important: </strong>The information in this document is <strong>Not Recommended</strong> and should not be used for new development.</p>
<div class="reflibtopic">
<p>Current information on this Reference Library topic can be found here:</p>
<ul>
<li><a href="http://developer.apple.com/referencelibrary/Java/idxPorting-date.html" target="_blank">Java > Porting</a></li>
</ul>
</div>
</div></div></div>
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">JavaSplashScreen</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/JavaAppLauncher.m</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/CustomView.h</option>
<option value="listing2.html">/CustomView.m</option>
<option value="listing3.html">/HelloWorld.java</option>
<option value="listing4.html">/JavaAppLauncher.h</option>
<option value="listing5.html">/JavaAppLauncher.m</option>
<option value="listing6.html">/main.m</option>
<option value="listing7.html">/README.txt</option>
<option value="listing8.html">/SplashScreen.h</option>
<option value="listing9.html">/SplashScreen.m</option></select>
</p>
</form>
<p><strong><a href="JavaSplashScreen.zip">Download Sample</a></strong> (“JavaSplashScreen.zip”, 166.5K)<BR>
<strong><a href="JavaSplashScreen.dmg">Download Sample</a></strong> (“JavaSplashScreen.dmg”, 227.7K)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">/*
File: JavaAppLauncher.m
Description: This file conains the functions used to read the startup options
for the Java Virtual Machine from the applications Java Dictionary
in the application bundles info.Plist, and a fuction to use this data
to start the JVM.
Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under Apple's
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Change History (most recent first):
*/
#import <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
#include <sys/stat.h>
#include <JavaVM/jni.h>
#include <unistd.h>
#include "JavaAppLauncher.h"
/*
* All debugging message use this prefix.
*/
#define ERR_PREFIX "[JavaAppLauncher Error] "
/*******
* Fetches the data in the Arguments key of the Java dictionary, and
* creates an array of Java Strings with this data to be passed into the applications main class.
* The Arguments key can either be a String or an Array. If it is a String then it
* is treated as a single argument, otherwise each item in the array is treated
* as a sperate argument.
*
* If Arguments key doesn't exit then it creates an empty array of strings for main.
********/
static jobjectArray getArgsForMain(JNIEnv *env, NSDictionary * javaDictionary) {
jarray cls = nil;
jarray ary = nil;
int index;
/* To create an array of strings we need to first look up the string class. */
cls = (*env)->FindClass(env, "java/lang/String");
if(cls != 0) { /* If we can't find java/lang/String then skip the rest, and return nothing. */
/* Fetch the Arguments object in the Java Dictionary */
id appArgs = [javaDictionary objectForKey:@"Arguments"];
/* If some arguments are specified then parse them */
if(appArgs != nil) {
/* The Arguments key of the Java dictionary can be a String or an Array */
if([appArgs isKindOfClass:[NSString class]]) {
/* The Arguments key of the Java dictionary is a single item in a String */
/* so, create a Java array of Strings with one item */
ary = (*env)->NewObjectArray(env,1, cls, 0);
if(ary != nil) {
/* Create a Java String from a UTF8 representation of the Arguments key */
jstring str = (*env)->NewStringUTF(env, [appArgs UTF8String]);
if(str != nil) {
/* Add this new Java String to our Java Array */
(*env)->SetObjectArrayElement(env, ary, 0, str);
/* Release our reference to the string once the */
/* Java array has a referenc to it */
(*env)->DeleteLocalRef(env, str);
}
}
} else if([appArgs isKindOfClass:[NSArray class]]) {
/* The Arguments key of the Java dictionary is an Array */
/* How many Arguments are we looking at */
int numberOfArgs = [appArgs count];
/* Create an array with the proper number of spaces */
ary = (*env)->NewObjectArray(env,numberOfArgs, cls, 0);
if(ary != nil)
/* Itterate over each item in the Arguments array */
for(index = 0;index < numberOfArgs; index++) {
/* Fetch the NSString representation of the Argument */
/* at the current index */
NSString * anArg = [appArgs objectAtIndex:index];
/* Create a Java String from a UTF8 representation */
/* of the this argument */
jstring str = (*env)->NewStringUTF(env, [anArg UTF8String]);
if(str != nil) {
/* Release our reference to the string once the */
/* Java array has a referenc to it */
(*env)->SetObjectArrayElement(env, ary, index, str);
(*env)->DeleteLocalRef(env, str);
}
}
}
else {
printf("Error: Arguments in the Java Dictionary of the info.plist is not\n");
printf("Error: a String or an Array of Strings.\n");
ary = (*env)->NewObjectArray(env, 0, cls, 0);
}
} else {
/* If an Arguments key is not defined then */
/* create an empty array of strings to pass in as args to main. */
ary = (*env)->NewObjectArray(env, 0, cls, 0);
}
}
else /* If we got here then we are just returning NULL */
fprintf(stderr, ERR_PREFIX "Error loading java/lang/String\n");
/* Return the java array */
return ary;
}
/***********
* The function, normalizeString, resolves the $APP_PACKAGE, and $JAVAROOT macros
* used in the java dictionary. $JAVAROOT and $APP_PACKAGE are purely conveniences
* to reduce the length of strings in the Info.plist file.
* $APP_PACKAGE is a special path string that represents the application bundle directory.
* $JAVAROOT defaults to APP_PACKAGE/Contents/Resources/Java.
***********/
static NSString * normalizeString(NSString * inString, NSDictionary * javaDictionary, BOOL releaseInString) {
NSString * pathToAppPackage;
NSString * javaRootProperty;
NSMutableString * workingString = [NSMutableString string];
NSMutableString * javaRootWorkingString = [NSMutableString string];
if(inString == nil)
return inString;
/* Make a new mutable copy of the inString to work with */
[workingString appendString:inString];
/* Get the path to the applications bundle */
pathToAppPackage = [[NSBundle mainBundle] bundlePath];
/* If the $JAVAROOT key is set in the java dictionary use its value */
javaRootProperty = [javaDictionary objectForKey:@"$JAVAROOT"];
if(javaRootProperty == nil) {
/* If it isn't set use the default location */
[javaRootWorkingString appendString:@"Contents/Resources/Java"];
} else {
[javaRootWorkingString appendString:javaRootProperty];
}
/* replace all $JAVAROOT with the javaRootWorkingString defined above */
[workingString replaceOccurrencesOfString:@"$JAVAROOT" withString:javaRootWorkingString
options:NSLiteralSearch range:NSMakeRange(0, [workingString length])];
/* replace all occurances of $APP_PACKAGE with the path to the applications bundle */
[workingString replaceOccurrencesOfString:@"$APP_PACKAGE" withString:pathToAppPackage
options:NSLiteralSearch range:NSMakeRange(0, [workingString length])];
/* Convienence feature since the inString is a non-mutable string */
if(releaseInString)
[inString autorelease];
return workingString;
}
/***********
* Some Java code expects various data files to be found relative to the current
* working directory. The function, getCWD, returns the working directory for this
* applicationw bundle. By default, the cwd is set to be the parent directory of the
* .app package, but it can be overridden by setting the WorkingDirectory key in
* the Java Dictionary.
***********/
static NSString * getCWD(NSDictionary * javaDictionary) {
/* First check to see if the key WorkingDirectory is defined in the Java dictionary. */
NSString * workingDir = [javaDictionary objectForKey:@"WorkingDirectory"];
if(workingDir != nil) {
/* Expand any macros in the value */
workingDir = normalizeString(workingDir,javaDictionary,YES);
}
else /* Use the path to the applications bundle */
workingDir = [[NSBundle mainBundle] bundlePath];
/* Get the file system version of this path */
const char * cStringWorkingDir = [workingDir fileSystemRepresentation];
/* Set the working directory for any tools */
if(chdir(cStringWorkingDir) != 0)
fprintf(stderr, ERR_PREFIX "Error setting the directory to %s\n",cStringWorkingDir);
return workingDir;
}
/***********
* The function, getClassPath, returns the class path defined by the ClassPath key
* in the java dictionary as the java.class.path property
* the ClassPath key can be either an array of Strings or a single String. If the
* ClassPath key is an array then the classpaths are combined in a colon seperated list.
***********/
static NSString * getClassPath(NSDictionary * javaDictionary) {
NSMutableString * javaClassPath = [NSMutableString string];
/* If the classpath is not defined then do nothing */
id classPathProperty = [javaDictionary objectForKey:@"ClassPath"];
if(classPathProperty == nil)
return nil;
/* The class path is passed in to the JVM as the java.class.path */
/* property. The JVM doesn't accept the -cp or -classpath option */
[javaClassPath appendString:@"-Djava.class.path="];
/* If it just a single string then we will use it as is */
if([classPathProperty isKindOfClass:[NSString class]]) {
[javaClassPath appendString:classPathProperty];
} else if([classPathProperty isKindOfClass:[NSArray class]]) {
/* The ClassPath key of the Java dictionary is an Array */
/* The class path property is a colon seperated list of paths*/
int index, count;
count = [classPathProperty count];
if(count > 0) {
/* Iterate though the list */
for(index = 0;index < count;index++) {
/* We dont want to start the list with a colon so only append */
/* a colon after the first path */
if(index != 0)
[javaClassPath appendString:@":"];
/* Append the classpath at index in the array */
[javaClassPath appendString:[classPathProperty objectAtIndex:index]];
}
}
}
else {
printf("Error: ClassPath in the Java Dictionary of the info.plist is not\n");
printf("Error: a String or an Array of Strings.\n");
return nil;
}
/* Resolve all macros in the class path , and return the result */
return normalizeString(javaClassPath,javaDictionary,YES);
}
/***********
* The function, getOptions(...), generates an array of JavaMVOptions to be used
* when calling JNI_CreateJavaVM. The function result is the number of options
* in the array. It uses the functions getClassPath(...), and getCWD(...).
***********/
static jint getOptions(JavaVMOption **options, NSDictionary * javaDictionary) {
jint numberOfOptions;
/* All the options will be first pushed into an NSMutableArray, then */
/* once we know how many options, we can allocate an array of JavaVMOption */
/* of the proper size */
/* Start with an array of one, if nothing else we will be setting the */
/* user.dir property */
NSMutableArray * optionArrary = [NSMutableArray arrayWithCapacity:1];
/* Start with the VMOptions */
id vmArgs = [javaDictionary objectForKey:@"VMOptions"];
if(vmArgs != nil) {
if([vmArgs isKindOfClass:[NSString class]])
/* The VMOptions key is a string so add it to our array of options */
[optionArrary addObject:vmArgs];
else
/* The VMOptions key of the Java dictionary is an Array*/
/* of NSStrings so we can just add its objects to our array */
[optionArrary addObjectsFromArray:vmArgs];
}
/* Add the java.class.path property if the ClassPath key is */
/* is defined in the JavaDictionary */
NSString * classPath = getClassPath(javaDictionary);
if(classPath != nil)
[optionArrary addObject:classPath];
/* Set the working direcory (pwd) of our Application */
/* The working directory is set by setting the Java */
/* property user.dir */
NSMutableString * userDir = [NSMutableString string];
[userDir appendString:@"-Duser.dir="];
[userDir appendString:getCWD(javaDictionary)];
[userDir appendString:@"/"];
[optionArrary addObject:userDir];
/* The Java Dictionaries Properties object is a list of key value pairs */
/* Itterate though each key value pair building a list of options */
/* in the form of -D{key}={value} */
NSDictionary * properties = [javaDictionary objectForKey:@"Properties"];
if(properties != nil) {
int index, count;
/* Get a list of the keys */
NSArray * keyArray = [properties allKeys];
count = [keyArray count];
if(count > 0) {
for(index = 0;index < count;index++) {
/*Now for each key get its value */
NSString * key = [keyArray objectAtIndex:index];
/* Build the property string */
NSMutableString * prop = [NSMutableString string];
[prop appendString:@"-D"];
[prop appendString:key];
[prop appendString:@"="];
[prop appendString:[properties objectForKey:key]];
[optionArrary addObject:prop];
}
}
}
/* Turn the OptionArrary into an array of JavaVMOptions */
numberOfOptions = [optionArrary count];
if(numberOfOptions > 0) {
int index;
/* Allocate enough space for the array of JavaVMOption's */
*options = malloc(numberOfOptions * sizeof(JavaVMOption));
/*Itterate though each option allocating space for each option string */
for(index = 0;index < numberOfOptions;index++) {
NSString * optionString = [optionArrary objectAtIndex:index];
/* Java uses UTF8 encoded Strings */
NSData * utf8Option =[optionString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
/* Allocate a buffer for each option string adding one byte for NULL termination*/
(*options)[index].optionString = malloc([utf8Option length]+1);
(*options)[index].extraInfo = NULL;
/*Get put the bytes of the UTF8 the buffer for the string */
[utf8Option getBytes:((*options)[index].optionString)];
/* Make sure it terminates with NULL */
(*options)[index].optionString[[utf8Option length]] = 0;
}
}
return numberOfOptions;
}
/*******
* StartupJava() assums that it is not being called on the applications main thread.
* It extracts the data needed to startup the JVM from this bundles Java dictionary
* in the info.pList. The main thread on Mac OS X is used to run AppKit's run loop.
********/
void startupJava() {
NSString * principalClassName;
JavaVMOption * options = NULL;
jint numberOfOptions;
NSDictionary * javaDictionary;
JNIEnv * env;
JavaVM * theVM;
JavaVMInitArgs vm_args;
jint result;
/* All of the Java VM startup options are contained in the Java Dictionary */
/* of the application bundles info.pList file. If the Java dictionary doesn't */
/* exist then bail */
javaDictionary = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"Java"];
if(javaDictionary == nil) {
fprintf(stderr, ERR_PREFIX "Java dictionary not found in info.Plist.\n");
return;
}
/* The JavaVMOption's array is used to pass in VMOptions, ClassPath, */
/* Working Directory, and any other properties that need to be defined */
numberOfOptions = getOptions(&options,javaDictionary);
/*
To invoke Java 1.4.1 or the currently preferred JDK as defined by the operating system (1.4.2 as of the release of this sample and the release of Mac OS X 10.4) nothing changes in 10.4 vs 10.3 in that when a JNI_VERSION_1_4 is passed into JNI_CreateJavaVM as the vm_args.version it returns the current preferred JDK.
To specify the current preferred JDK in a family of JVM's, say the 1.5.x family, applications should set the environment variable JAVA_JVM_VERSION to 1.5, and then pass JNI_VERSION_1_4 into JNI_CreateJavaVM as the vm_args.version. To get a specific Java 1.5 JVM, say Java 1.5.0, set the environment variable JAVA_JVM_VERSION to 1.5.0. For Java 1.6 it will be the same in that applications will need to set the environment variable JAVA_JVM_VERSION to 1.6 to specify the current preferred 1.6 Java VM, and to get a specific Java 1.6 JVM, say Java 1.6.1, set the environment variable JAVA_JVM_VERSION to 1.6.1.
To make this sample bring up the current preferred 1.5 JVM, set the environment variable JAVA_JVM_VERSION to 1.5 before calling JNI_CreateJavaVM as shown below. Applications must currently check for availability of JDK 1.5 before requesting it. If your application requires JDK 1.5 and it is not found, it is your responsibility to report an error to the user. To verify if a JVM is installed, check to see if the symlink, or directory exists for the JVM in /System/Library/Frameworks/JavaVM.framework/Versions/ before setting the environment variable JAVA_JVM_VERSION.
If the environment variable JAVA_JVM_VERSION is not set, and JNI_VERSION_1_4 is passed into JNI_CreateJavaVM as the vm_args.version, JNI_CreateJavaVM will return the current preferred JDK. Java 1.4.2 is the preferred JDK as of the release of this sample and the release of Mac OS X 10.4.
*/
{
NSString * targetJVM = @"1.5";
NSString * TargetJavaVM;
UInt8 pathToTargetJVM [PATH_MAX] = "\0";
struct stat sbuf;
// Look for the JavaVM bundle using its identifier, then get it's path. Append the Version component, and the
// desired target JVM component to the path.
TargetJavaVM = [[[[NSBundle bundleWithIdentifier: @"com.apple.JavaVM"] bundlePath] stringByAppendingPathComponent:@"Versions"] stringByAppendingPathComponent:targetJVM];
if([TargetJavaVM getFileSystemRepresentation:(char*)pathToTargetJVM maxLength:PATH_MAX]) {
// Check to see if the directory, or a sym link for the target JVM directory exists, and if so set the
// environment variable JAVA_JVM_VERSION to the target JVM.
if(stat((char*)pathToTargetJVM,&sbuf) == 0) {
// Ok, the directory exists, so now we need to set the environment var JAVA_JVM_VERSION to the CFSTR targetJVM
// We can reuse the pathToTargetJVM buffer to set the environement var.
if([targetJVM getFileSystemRepresentation:(char*)pathToTargetJVM maxLength:PATH_MAX])
setenv("JAVA_JVM_VERSION", (char*)pathToTargetJVM,1);
}
}
}
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = numberOfOptions;
vm_args.ignoreUnrecognized = JNI_TRUE;
/*******
* Use JNI_CreateJavaVM to create a VM instance
*******/
result = JNI_CreateJavaVM(&theVM, (void**)&env, &vm_args);
if ( result != 0 ) {
fprintf(stderr, ERR_PREFIX "Error starting up VM.\n");
return;
}
/* We will load and execute the class specified in the Java dictionary "MainClass" key */
principalClassName = [javaDictionary objectForKey:@"MainClass"];
/* Find the class. */
jclass mainClass = (*env)->FindClass(env, [principalClassName UTF8String]);
if ( mainClass == nil ) {
(*env)->ExceptionDescribe(env);
goto leave;
}
/* Get the application's main method */
jmethodID mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
"([Ljava/lang/String;)V");
if (mainID == nil) {
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
} else {
fprintf(stderr, ERR_PREFIX "No main method found in specified class.\n");
}
goto leave;
}
/* * Fetches the data in the Arguments key of the Java dictionary, and */
/* creates an array of Java Strings with this data to be passed into the */
/* applications main class. */
jobjectArray mainArgs = getArgsForMain(env,javaDictionary);
/* Invoke the main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
goto leave;
}
/* Detach the current thread so that it appears to have exited when */
/* the application's main method exits. */
if ((*theVM)->DetachCurrentThread(theVM) != 0) {
fprintf(stderr, ERR_PREFIX "Could not detach main thread.\n");
goto leave;
}
leave:
/* Unloads a Java VM and reclaims its resources. The system waits */
/* until the main thread is only remaining user thread before it destroys */
/* the VM. */
(*theVM)->DestroyJavaVM(theVM);
}
</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/JavaSplashScreen/listing5.html%3Fid%3DDTS10000682-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/JavaSplashScreen/listing5.html%3Fid%3DDTS10000682-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/JavaSplashScreen/listing5.html%3Fid%3DDTS10000682-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>