(This is a long one, it explains how I discovered that something I do almost every day to improve my coding is actually a little ritual that has much in common with practice in the martial arts…)
This all starts with the way RubLog, some blogging software I once wrote, does searching (but it isn’t an article about searching, or about bit twiddling. Trust me). Because I eventually wanted to use cosine-based comparisons to find similar articles, I build vectors mapping word occurrences to each document in the blog. I basically ended up with a set of 1,200-1,500 bits for each document. To implement a basic ranked search, I needed to be able to perform a bitwise AND between each of these vectors and a vector containing the search terms, and then count the number of one-bits in the result.
I had a spare 45 minutes last night (I took Zachary to his karate lesson, but there was no room in the parent’s viewing area), so I thought I’d play with this. First I tried storing the bit vectors different ways: it turns out (to my surprise) that storing them as an array of fixnums has almost exactly the same speed as storing them as the bits in a bignum. (Also, rather pleasingly, changing between the two representations involves altering just two lines of code). Because it marshals far more compactly, I decided to stick with the bignum.
Then I had fun playing with the bit counting itself. The existing code uses the obvious algorithm:
1
|
|
Just how slow was this? I wrote a simple testbed that generated one hundred 1,000 bit vectors, each with 20 random bits set, and timed the loop. For all 100, it took about .4s.
Then I tried using the ‘divide-and-conquer’ counting algorithm from chapter 5 of Hacker’s Delight (modified to deal with chunking the Bignum into 30-bit words).
1 2 3 4 5 6 7 8 9 |
|
This ran about 2.5 times faster that the naive algorithm.
Then I realized that when I was comparing a set of search times with just a few words in it, the bit vector would be very sparse. Each chunk in the loop above would be likely to be zero. So I added a test:
1 2 3 4 5 6 7 8 9 10 |
|
Now I was seven times faster than the original. But my testbed was using vectors containing 20 set bits (out of 1,000). I changed it to generate timings with vectors containing 1, 2, 5, 10, 20, 100, and 900 set bits. This got even better: I was up to a factor of 15 faster with 1 or 2 bits in the vector.
But if I could speed things up this much by eliminating zero chunks in the bit-twiddling algorithm could I do the same in the simple counting algorithm? I tried a third algorithm:
1 2 3 4 5 |
|
The inner loop here is the same as for the original count, but I now count the bits in chunks of 30.
This code performs identically to the bit-twiddling code for 1 set bit, and only slightly worse for 2 set bits. However. once the number of bits starts to grow (past about 5 for my given chunk size), the performance starts to tail off. At 100 bits it’s slower than the original naive count.
So for my particular application, I could probably chose either of the chunked counting algorithms. Because the bit twiddling one scales up to larger numbers of bits, and because I’ll need that later on if I ever start doing the cosine-based matching of documents, I went with it.
So what’s the point of all this?
Yesterday I posted a blog entry about the importance of verbs. It said “Often the true value of a thing isn’t the thing itself, but instead is the activity that created it.” Chad Fowler picked this up and wrote a wonderful piece showing how this was true for musicians. And Brian Marick picked up of Chad’s piece to emphasize the value of practice when learning a creative process.
At the same time, Andy and I had been discussing a set of music tapes he had. Originally designed to help musicians practice scales and arpeggios, these had been so popular that they now encompassed a whole spectrum of practice techniques. We were bemoaning the fact that it seemed unlikely that we’d be able to get developers to do the same: to buy some aid to help them practice programming. We just felt that practicing was not something that programmers did.
Skip forward to this morning. In the shower, I got to thinking about this, and realized that my little 45 minute exploration of bit counting was actually a practice session. I wasn’t really worried about the performance of bit counting in the blog’s search algorithm; in reality it comes back pretty much instantaneously. Instead, I just wanted to play with some code and experiment with a technique I hadn’t used before. I did it in a simple, controlled environment, and I tried many different variations (more than I’ve listed here). And I’ve still got some more playing to do: I want to mess around with the effect of varying the chunk size, and I want to see if any of the other bit counting algorithms perform faster.
What made this a practice session? Well, I had some time without interruptions. I had a simple thing I wanted to try, and I tried it many times. I looked for feedback each time so I could work to improve. There was no pressure: the code was effectively throwaway. It was fun: I kept making small steps forward, which motivated me to continue. Finally, I came out of it knowing more than when I went in.
Ultimately it was having the free time that allowed me to practice. If the pressure was on, if there was a deadline to delivery the blog search functionality, then the existing performance would have been acceptable, and the practice would never have taken place. But those 45 pressure-free minutes let me play.
So how can we do this in the real world? How can we help developers do the practicing that’s clearly necessary in any creative process? I don’t know, but my gut tells me we need to do two main things.
The first is to take the pressure off every now and then. Provide a temporal oasis where it’s OK not to worry about some approaching deadline. It has to be acceptable to relax, because if you aren’t relaxed you’re not going to learn from the practice.
The second is to help folks learn how to play with code: how to make mistakes, how to improvise, how to reflect, and how to measure. This is hard: we’re trained to try to do things right, to play to the score, rather than improvise. I suspect that success here comes only after doing.
 You don’t necessarily have to look at performance: perhaps you could play with the structure, or the memory use, or the interface. In the end it doesn’t matter. Experiment, measure, improve.
Practice.


bsModalBuilder is a tool for building Bootstrap modals that are tailored to your specific needs, one modal at a time, without reusing the same markup. Each dynamically created modal is built specifically for that single task, using The Power of JavaScript™ :)
bsModalBuilder.js
after main Bootstrap 3 JavaScript files,var Modal = new ModalBuilder();
,Modal.modal(options);
Simple modal example.
var modal = Modal.modal( 'Example 1', 'This is an example 1!', { submit: function() { alert('Modal has been confirmed.'); }, dismiss: function() { alert('Modal has been dismissed.'); } }, { size: null, buttons: [ { text: 'Dismiss', type: 'dismiss', style: 'btn-default' }, { text: ' Confirm', type: 'submit', style: 'btn-primary' } ], onloadCallback: function(mId) { console.info('Modal loaded, ID:', mId); }, oncloseCallback: function(mId) { console.log('Modal closed, ID:', mId); } } );
Modal builder supports two ways of modal generation, fully automated or manual.
alert()
equivalent,confirm()
equivalent,prompt()
equivalent,


Monitoring and Management Using JMX Technology
The Java virtual machine (Java VM) has built-in instrumentation that enables you to monitor and manage it using the Java Management Extensions (JMX) technology. These built-in management utilities are often referred to as out-of-the-box management tools for the Java VM. You can also monitor any appropriately instrumented applications using the JMX API.
Setting System Properties
To enable and configure the out-of-the-box JMX agent so that it can monitor and manage the Java VM, you must set certain system properties when you start the Java VM. You set a system property on the command-line as follows.
java -Dproperty=value ...
You can set any number of system properties in this way. If you do not specify a value for a management property, then the property is set with its default value. The full set of out-of-the-box management properties is described in Table 2-1 at the end of this chapter. You can also set system properties in a configuration file, as described in Out-of-the-Box Monitoring and Management Properties.
Note - To run the Java VM from the command line, you must add JRE_HOME/bin to your path, where JRE_HOME is the directory containing the Java Runtime Environment (JRE) implementation. Alternatively, you can enter the full path when you type the command.
The following documents describe the syntax and the full set of command-line options supported by the Java HotSpot VMs.
Enabling the Out-of-the-Box Management
To monitor a Java platform using the JMX API, you must do the following.
-
Enable the JMX agent (another name for the platform MBean server) when you start the Java VM. You can enable the JMX agent for:
-
Local monitoring, for a client management application running on the local system.
-
Remote monitoring, for a client management application running on a remote system.
-
-
Monitor the Java VM with a tool that complies to the JMX specification, such as JConsole. See Chapter 3, Using JConsole for more information about Console.
These steps are described in the next sections.
Local Monitoring and Management
Under previous releases of the Java SE platform, to allow the JMX client access to a local Java VM, you had to set the following system property when you started the Java VM or Java application.
com.sun.management.jmxremote
Setting this property registered the Java VM platform's MBeans and published the Remote Method Invocation (RMI) connector via a private interface to allow JMX client applications to monitor a local Java platform, that is, a Java VM running on the same machine as the JMX client.
In the Java SE 6 platform, it is no longer necessary to set this system property. Any application that is started on the Java SE 6 platform will support the Attach API, and so will automatically be made available for local monitoring and management when needed.
For example, previously, to enable the JMX agent for the Java SE sample application Notepad, you would have to run the following commands.
% cd JDK_HOME/demo/jfc/Notepad % java -Dcom.sun.management.jmxremote -jar Notepad.jar
In the above command, JDK_HOME is the directory in which the Java Development Kit (JDK) is installed. In the Java SE 6 platform, you would simply have to run the following command to start Notepad.
% java -jar Notepad.jar
Once Notepad has been started, a JMX client using the Attach API can then enable the out-of-the-box management agent to monitor and manage the Notepad application.
Note - On Windows platforms, for security reasons, local monitoring and management is only supported if your default temporary directory is on a file system that allows the setting of permissions on files and directories (for example, on a New Technology File System (NTFS) file system). It is not supported on a File Allocation Table (FAT) file system, which provides insufficient access controls.
Local Monitoring and Management Using JConsole
Local monitoring with JConsole is useful for development and creating prototypes. Using JConsole locally is not recommended for production environments, because JConsole itself consumes significant system resources. Rather, you should use JConsole on a remote system to isolate it from the platform being monitored.
However, if you do wish to perform local monitoring using JConsole, you start the tool by typing jconsole in a command shell. When you start jconsole without any arguments, it will automatically detect all local Java applications, and display a dialog box that enables you to select the application you want to monitor. Both JConsole and the application must by executed by the same user, since the monitoring and management system uses the operating system's file permissions.
Note - To run JConsole from the command line, you must add JDK_HOME/bin to your path. Alternatively, you can enter the full path when you type the command.
For more information, see Chapter 3, Using JConsole.
Remote Monitoring and Management
To enable monitoring and management from remote systems, you must set the following system property when you start the Java VM.
com.sun.management.jmxremote.port=portNum
In the property above, portNum is the port number through which you want to enable JMX RMI connections. Be sure to specify an unused port number. In addition to publishing an RMI connector for local access, setting this property publishes an additional RMI connector in a private read-only registry at the specified port using a well known name, "jmxrmi".
Note - You must set the above system property in addition to any properties you might set for security.
Remote monitoring and management requires security to ensure that unauthorized persons cannot control or monitor your application. Password authentication over the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) is enabled by default. You can disable password authentication and SSL separately, as described in the next sections.
Note - For production systems, use both SSL client certificates to authenticate the client host and password authentication for user management. See the topics Using SSL and Using LDAP Authentication for more information.
The Java platform supports pluggable login modules for authentication. You can plug in any login module depending on the authentication infrastructure in your organization. The section titled Using LDAP Authentication describes how to plug in the com.sun.security.auth.module.LdapLoginModule for Lightweight Directory Access Protocol (LDAP) based authentication.
After you have enabled the JMX agent for remote use, you can monitor your application using JConsole, as described in Remote Monitoring with JConsole. How to connect to the management agent programmatically is described in Connecting to the JMX Agent Programmatically.
Using Password Authentication
Using LDAP Authentication
The JMXAuthenticator
implementation in the JMX agent is based on Java Authentication and
Authorization Service (JAAS) technology. Authentication is
performed by passing the user credentials to a JAAS javax.security.auth.spi.LoginModule
object. The
com.sun.security.auth.module.LdapLoginModule class enables
authentication using LDAP. You can replace the default
LoginModule
class with the
LdapLoginModule
as described next.
Create a JAAS configuration file that would work in the required
business organization. An example of a configuration file
(ldap.config
) is shown next:
ExampleCompanyConfig { com.sun.security.auth.module.LdapLoginModule REQUIRED userProvider="ldap://example-ds/ou=people,dc=examplecompany,dc=com" userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))" authzIdentity=monitorRole; };
The options in the configuration file are briefly explained next. See documentation for the com.sun.security.auth.module.LdapLoginModule class for information about the configuration options shown in the code snippet.
- The
com.sun.security.auth.module.LdapLoginModule REQUIRED
option means that authentication usingLdapLoginModule
is required in order for overall authentication to be successful - The
userProvider
option identifies the LDAP server and the position in the directory tree where user entries are located - The
userFilter
option specifies the search filter to use to locate a user entry in the LDAP directory. The token{USERNAME}
is replaced with the user name before the filter is used to search the directory. - The
authzIdentity
option specifies the access role for authenticated users. In the example, authenticated users will have themonitorRole
. See the Access Files section for more information.
Start your application with the following properties set on the command line:
com.sun.management.jmxremote.login.config
- This property configures the JMX agent to use the specified JAAS configuration entry.java.security.auth.login.config
- specifies the path to the JAAS configuration file.
A sample command line is shown next.
java -Dcom.sun.management.jmxremote.port=5000 -Dcom.sun.management.jmxremote.login.config=ExampleCompanyConfig -Djava.security.auth.login.config=ldap.config -jar MyApplication.jar
Using File-Based Password Authentication
The file-based password authentication mechanism supported by the JMX agent stores the password in clear-text and is intended only for development use. For production use, it is strongly recommended that you use SSL client certificates for authentication or plug in a secure login configuration.
Caution - A potential security issue has been identified with password authentication for remote connectors when the client obtains the remote connector from an insecure RMI registry (the default). If an attacker starts a bogus RMI registry on the target server before the legitimate registry is started, then the attacker can steal clients' passwords. This scenario includes the case where you launch a Java VM with remote management enabled, using the system property com.sun.management.jmxremote.port=portNum, even when SSL is enabled. Although such attacks are likely to be noticed, it is nevertheless a vulnerability.
By default, when you enable the JMX agent for remote monitoring, it uses password authentication. However, the way you set it up depends on whether you are in a single-user environment or a multiple-user environment.
Since passwords are stored in clear-text in the password file, it is not advisable to use your regular user name and password for monitoring. Instead, use the user names specified in the password file such as monitorRole and controlRole. For more information, see Using Password and Access Files.
To Set up a Single-User Environment
You set up the password file in the JRE_HOME/lib/management directory as follows.
- Copy the password template file, jmxremote.password.template, to jmxremote.password.
- Set file permissions so that only the owner can read and write the password file.
- Add passwords for roles such as monitorRole and controlRole.
To Set up a Multiple-User Environment
You set up the password file in the JRE_HOME/lib/management directory as follows.
- Copy the password template file, jmxremote.password.template, to your home directory and rename it to jmxremote.password.
- Set file permissions so that only you can read and write the password file.
- Add passwords for the roles such as monitorRole and controlRole.
- Set the following system property when you start the Java
VM.
com.sun.management.jmxremote.password.file=pwFilePath
In the above property, pwFilePath is the path to the password file.
Disabling Password Authentication
Password authentication for remote monitoring is enabled by default. To disable it, set the following system property when you start the Java VM.
com.sun.management.jmxremote.authenticate=false
Caution - This configuration is insecure. Any remote user who knows (or guesses) your JMX port number and host name will be able to monitor and control your Java application and platform. While it may be acceptable for development, it is not recommended for production systems.
When you disable password authentication, you can also disable SSL, as described in Disabling Security. You may also want to disable passwords, but use SSL client authentication, as described in Enabling SSL Client Authentication.
Using SSL
SSL is enabled by default when you enable remote monitoring and management. To use SSL, you need to set up a digital certificate on the system where the JMX agent (the MBean server) is running and then configure SSL properly. You use the command-line utility keytool to work with certificates. The general procedure is as follows.
To Set up SSL
- If you do not already have a key pair and certificate set up
on the server:
-
Generate a key pair with the keytool -genkey command.
-
Request a signed certificate from a certificate authority (CA) with the keytool -certreq command.
-
Import the certificate into your keystore with the keytool -import command. See Importing Certificates in the keytool documentation.
For more information and examples, see keytool - Key and Certificate Management Tool (Solaris, Linux, or Mac OS X) or (Windows platforms).
-
- Configure SSL on the server system.
A full explanation of configuring and customizing SSL is beyond the scope of this document, but you generally need to set the system properties described in the list below.
- System Property
-
Description
- javax.net.ssl.keyStore
-
Keystore location.
- javax.net.ssl.keyStoreType
-
Default keystore type.
- javax.net.ssl.keyStorePassword
-
Default keystore password.
- javax.net.ssl.trustStore
-
Truststore location.
- javax.net.ssl.trustStoreType
-
Default truststore type.
- javax.net.ssl.trustStorePassword
-
Default truststore password.
For more information about setting system properties, see Setting System Properties above, or consult the following documents.
Enabling RMI Registry Authentication
When setting up connections for monitoring remote applications, you can optionally bind the RMI connector stub to an RMI registry that is protected by SSL. This allows clients with the appropriate SSL certificates to get the connector stub that is registered in the RMI registry. To protect the RMI registry using SSL, you must set the following system property.
com.sun.management.jmxremote.registry.ssl=true
When this property is set to true, an RMI registry protected by SSL will be created and configured by the out-of-the-box management agent when the Java VM is started. The default value of this property is false. If this property is set to true, in order to have full security then SSL client authentication must also be enabled, as described in the next section.
Enabling SSL Client Authentication
To enable SSL client authentication, set the following system property when you start the Java VM.
com.sun.management.jmxremote.ssl.need.client.auth=true
SSL must be enabled (default is set to false), to use client SSL authentication. This configuration requires the client system to have a valid digital certificate. You must install a certificate and configure SSL on the client system, as described in Using SSL. As stated in the previous section, if RMI registry SSL protection is enabled, then client SSL authentication must be set to true.
Disabling SSL
To disable SSL when monitoring remotely, you must set the following system property when you start the Java VM.
com.sun.management.jmxremote.ssl=false
Password authentication will still be required unless you disable it, as specified in Disabling Password Authentication.
Disabling Security
To disable both password authentication and SSL (namely to disable all security), you should set the following system properties when you start the Java VM.
com.sun.management.jmxremote.authenticate=false com.sun.management.jmxremote.ssl=false
Caution - This configuration is insecure: any remote user who knows (or guesses) your port number and host name will be able to monitor and control your Java applications and platform. Furthermore, possible harm is not limited to the operations you define in your MBeans. A remote client could create a javax.management.loading.MLet MBean and use it to create new MBeans from arbitrary URLs, at least if there is no security manager. In other words, a rogue remote client could make your Java application execute arbitrary code.
Consequently, while disabling security might be acceptable for development, it is strongly recommended that you do not disable security for production systems.
Remote Monitoring with JConsole
You can remotely monitor an application using JConsole, with or without security enabled.
Remote Monitoring with JConsole with SSL Disabled
To monitor a remote application with SSL disabled, you would start JConsole with the following command.
% jconsole hostName:portNum
You can also omit the host name and port number, and enter them in the dialog box that JConsole provides.
Remote Monitoring with JConsole with SSL Enabled
To monitor a remote application with SSL enabled, you need to set up the truststore on the system where JConsole is running and configure SSL properly. For example, you can create a keystore as described in the JSSE Guide and start your application (called Server in this example) with the following commands.
% java -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password Server
If you created the keystore and started Server as shown above, then you would have to start JConsole as follows.
% jconsole -J-Djavax.net.ssl.trustStore=truststore \ -J-Djavax.net.ssl.trustStorePassword=trustword
The above configuration authenticates the server only. If SSL client authentication is set up, you will need to provide a similar keystore for JConsole's keys, and an appropriate truststore for the application.
See Customizing the Default Key and Trust Stores, Store Types, and Store Passwords in the JSSE Guide for information.
For more information on using JConsole, see Chapter 3, Using JConsole.
Using Password and Access Files
The password and access files control security for remote monitoring and management. These files are located by default in JRE_HOME/lib/management and are in the standard Java properties file format. For more information on the format, see the API reference for the java.util.Properties package.
Password Files
The password file defines the different roles and their passwords. The access control file (jmxremote.access by default) defines the permitted access for each role. To be functional, a role must have an entry in both the password and the access files.
The JRE implementation contains a password file template named jmxremote.password.template. Copy this file to JRE_HOME/lib/management/jmxremote.password or to your home directory, and add the passwords for the roles defined in the access file.
You must ensure that only the owner has read and write permissions on this file, since it contains the passwords in clear text. For security reasons, the system checks that the file is only readable by the owner and exits with an error if it is not. Thus in a multiple-user environment, you should store the password file in private location such as your home directory.
Property names are roles, and the associated value is the role's password. For example, the following are sample entries in the password file.
Example 2-1 An Example Password File# specify actual password instead of the text password monitorRole password controlRole password
On Solaris, Linux, or Mac OS X operating systems, you can set the file permissions for the password file by running the following command.
chmod 600 jmxremote.password
For instructions on how to set file permissions on Windows platforms, see Appendix A, Additional Security Information For Microsoft Windows.
Access Files
By default, the access file is named jmxremote.access. Property names are identities from the same space as the password file. The associated value must be either readonly or readwrite.
The access file defines roles and their access levels. By default, the access file defines the two following primary roles.
-
monitorRole, which grants read-only access for monitoring.
-
controlRole, which grants read-write access for monitoring and management.
An access control entry consists of a role name and an associated access level. The role name cannot contain spaces or tabs and must correspond to an entry in the password file. The access level can be either one of the following.
-
readonly, which grants access to read an MBean's attributes. For monitoring, this means that a remote client in this role can read measurements but cannot perform any action that changes the environment of the running program. The remote client can also listen to MBean notifications.
-
readwrite, which grants access to read and write an MBean's attributes, to invoke operations on them, and to create or remove them. This access should be granted to only trusted clients, since they can potentially interfere with the operation of an application.
A role should have only one entry in the access file. If a role has no entry, it has no access. If a role has multiple entries, then the last entry takes precedence. Typical predefined roles in the access file resemble the following.
Example 2-2 An Example Access File# The "monitorRole" role has readonly access. # The "controlRole" role has readwrite access. monitorRole readonly controlRole readwrite
Out-of-the-Box Monitoring and Management Properties
You can set out-of-the-box monitoring and management properties in a configuration file or on the command line. Properties specified on the command line override properties in a configuration file. The default location for the configuration file is JRE_HOME/lib/management/management.properties. The Java VM reads this file if either of the command-line properties com.sun.management.jmxremote or com.sun.management.jmxremote.port are set. Management via the Simple Network Management Protocol (SNMP) uses the same configuration file. For more information about SNMP monitoring, see Chapter 5, SNMP Monitoring and Management.
You can specify a different location for the configuration file with the following command-line option.
com.sun.management.config.file=ConfigFilePath
In the property above, ConfigFilePath is the path to the configuration file.
Table 2-1 describes all the out-of-the-box monitoring and management properties.
| Property | Description | Values |
|---|---|---|
|
com.sun.management.jmxremote |
Enables the JMX remote agent and local monitoring via a JMX connector published on a private interface used by JConsole and any other local JMX clients that use the Attach API. JConsole can use this connector if it is started by the same user as the user that started the agent. No password or access files are checked for requests coming via this connector. |
true / false. Default is true. |
|
com.sun.management.jmxremote. port |
Enables the JMX remote agent and creates a remote JMX connector to listen through the specified port. By default, the SSL, password, and access file properties are used for this connector. It also enables local monitoring as described for the com.sun.management.jmxremote property. |
Port number. No default. |
|
com.sun.management.jmxremote. registry.ssl |
Binds the RMI connector stub to an RMI registry protected by SSL. |
true / false. Default is false. |
|
com.sun.management.jmxremote. ssl |
Enables secure monitoring via SSL. If false, then SSL is not used. |
true / false. Default is true. |
|
com.sun.management.jmxremote. ssl.enabled.protocols |
A comma-delimited list of SSL/TLS protocol versions to enable. Used in conjunction with com.sun.management.jmxremote.ssl. |
Default SSL/TLS protocol version. |
|
com.sun.management.jmxremote. ssl.enabled.cipher.suites |
A comma-delimited list of SSL/TLS cipher suites to enable. Used in conjunction with com.sun.management.jmxremote.ssl. |
Default SSL/TLS cipher suites. |
|
com.sun.management.jmxremote. ssl.need.client.auth |
If this property is true and the property com.sun.management.jmxremote.ssl is also true, then client authentication will be performed. |
true / false. Default is false. |
|
com.sun.management.jmxremote. authenticate |
If this property is false then JMX does not use passwords or access files: all users are allowed all access. |
true / false. Default is true. |
|
com.sun.management.jmxremote. password.file |
Specifies location for password file. If com.sun.management.jmxremote.authenticate is false, then this property and the password and access files are ignored. Otherwise, the password file must exist and be in the valid format. If the password file is empty or nonexistent, then no access is allowed. |
JRE_HOME/lib/management/ jmxremote.password |
|
com.sun.management.jmxremote. access.file |
Specifies location for the access file. If com.sun.management.jmxremote.authenticate is false, then this property and the password and access files are ignored. Otherwise, the access file must exist and be in the valid format. If the access file is empty or nonexistent, then no access is allowed. |
JRE_HOME/lib/management/ jmxremote.access |
|
Specifies the name of a Java Authentication and Authorization Service (JAAS) login configuration entry to use when the JMX agent authenticates users. When using this property to override the default login configuration, the named configuration entry must be in a file that is loaded by JAAS. In addition, the login modules specified in the configuration should use the name and password callbacks to acquire the user's credentials. For more information, see the API documentation for javax.security.auth.callback.NameCallback and javax.security.auth.callback.PasswordCallback. |
Default login configuration is a file-based password authentication. |
Configuration Errors
If any errors occur during start up of the MBean server, the RMI registry, or the connector, the Java VM will throw an exception and exit. Configuration errors include the following.
-
Failure to bind to the port number.
-
Invalid password file.
-
Invalid access file.
-
Password file is readable by users other than the owner.
If your application runs a security manager, then additional permissions are required in the security permissions file.
Connecting to the JMX Agent Programmatically
Once you have enabled the JMX agent, a client can use the following URL to access the monitoring service.
service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi
A client can create a connector for the agent by instantiating a javax.management.remote.JMXServiceURL object using the URL, and then creating a connection using the JMXConnectorFactory.connect method, shown in Example 2-3.
Example 2-3 Creating a Connection Using JMXConnectorFactory.connectJMXServiceURL u = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://" + hostName + ":" + portNum + "/jmxrmi"); JMXConnector c = JMXConnectorFactory.connect(u);
Setting up Monitoring and Management Programmatically
As stated previously, in the Java SE platform version 6, you can create a JMX client that uses the Attach API to enable out-of-the-box monitoring and management of any applications that are started on the Java SE 6 platform, without having to configure the applications for monitoring when you launch them. The Attach API provides a way for tools to attach to and start agents in the target application. Once an agent is running, JMX clients (and other tools) are able to obtain the JMX connector address for that agent via a property list that is maintained by the Java VM on behalf of the agents. The properties in the list are accessible from tools that use the Attach API. So, if an agent is started in an application, and if the agent creates a property to represent a piece of configuration information, then that configuration information is available to tools that attach to the application.
The JMX agent creates a property with the address of the local JMX connector server. This allows JMX tools to attach to and get the connector address of an agent, if it is running.
Example 2-4 shows code that could be used in a JMX tool to attach to a target VM, get the connector address of the JMX agent and connect to it.
Example 2-4 Attaching a JMX tool to a connector and getting the agent's addressstatic final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; // attach to the target application VirtualMachine vm = VirtualMachine.attach(id); // get the connector address String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); // no connector address, so we start the JMX agent if (connectorAddress == null) { String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"; vm.loadAgent(agent); // agent is started, get the connector address connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); } // establish connection to connector server JMXServiceURL url = new JMXServiceURL(connectorAddress); JMXConnector = JMXConnectorFactory.connect(url);
Example 2-4 uses the com.sun.tools.attach.VirtualMachine class's attach() method to attach to a given Java VM so that it can read the properties that the target Java VM maintains on behalf of any agents running in it. If an agent is already running, then the VirtualMachine class's getAgentProperties() method is called to obtain the agent's address. The getAgentProperties() method returns a string property for the local connector address com.sun.management.jmxremote.localConnectorAddress, that you can use to connect to the local JMX agent.
If no agent is running already, then one is loaded by the VirtualMachine from JRE_HOME/lib/management-agent.jar, and its connector address is obtained by getAgentProperties().
A connection to the agent is then established by calling JMXConnectorFactory.connect on a JMX service URL that has been constructed from this connector address.
Mimicking Out-of-the-Box Management Using the JMX Remote API
As explained above, remote access to the out-of-the-box management agent is protected by authentication and authorization, and by SSL encryption, and all configuration is performed by setting system properties or by defining a management.properties file. In most cases, using the out-of-the-box management agent and configuring it through the management.properties file is more than sufficient to provide secure management of remote Java VMs. However, in some cases greater levels of security are required and in other cases certain system configurations do not allow the use of a management.properties file. Such cases might involve exporting the RMI server's remote objects over a certain port to allow passage through a firewall, or exporting the RMI server's remote objects using a specific network interface in multi-homed systems. For such cases, the behavior of the out-of-the-box management agent can be mimicked by using the JMX Remote API directly to create, configure and deploy the management agent programmatically.
Example of Mimicking Out-of-the-Box Management
This section provides an example of how to implement a JMX agent that identically mimics an out-of-the-box management agent. In exactly the same way as the out-of-the-box management agent, the agent created in Example 2-5 will run on port 3000, will have a password file named password.properties, an access file named access.properties and it will implement the default configuration for SSL/TLS-based RMI Socket Factories, requiring server authentication only. This example assumes a keystore has already been created, as described in Using SSL. Information about how to set up the SSL configuration can be found in the JSSE Reference Guide.
To enable monitoring and management on an application named com.example.MyApp using the out-of-the-box JMX agent with the configuration described above, you would run com.example.MyApp with the following command.
% java -Dcom.sun.management.jmxremote.port=3000 \ -Dcom.sun.management.jmxremote.password.file=password.properties \ -Dcom.sun.management.jmxremote.access.file=access.properties \ -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password \ com.example.MyApp
Note - The com.sun.management.jmxremote.* properties could have been specified in a management.properties file instead of passing them at the command line. In that case, the system property -Dcom.sun.management.config.file=management.properties would be required to specify the location of the management.properties file.
Example 2-5 shows the code you would need to write to create programmatically a JMX agent that will allow exactly the same monitoring and management on com.example.MyApp as would be possible using the command above.
Example 2-5 Mimicking an Out-of-the-Box JMX Agent Programmaticallypackage com.example; import java.lang.management.*; import java.rmi.registry.*; import java.util.*; import javax.management.*; import javax.management.remote.*; import javax.management.remote.rmi.*; import javax.rmi.ssl.*; public class MyApp { public static void main(String[] args) throws Exception { // Ensure cryptographically strong random number generator used // to choose the object number - see java.rmi.server.ObjID // System.setProperty("java.rmi.server.randomIDs", "true"); // Start an RMI registry on port 3000. // System.out.println("Create RMI registry on port 3000"); LocateRegistry.createRegistry(3000); // Retrieve the PlatformMBeanServer. // System.out.println("Get the platform's MBean server"); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // Environment map. // System.out.println("Initialize the environment map"); HashMap<String,Object> env = new HashMap<String,Object>(); // Provide SSL-based RMI socket factories. // // The protocol and cipher suites to be enabled will be the ones // defined by the default JSSE implementation and only server // authentication will be required. // SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory(); env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf); env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf); // Provide the password file used by the connector server to // perform user authentication. The password file is a properties // based text file specifying username/password pairs. // env.put("jmx.remote.x.password.file", "password.properties"); // Provide the access level file used by the connector server to // perform user authorization. The access level file is a properties // based text file specifying username/access level pairs where // access level is either "readonly" or "readwrite" access to the // MBeanServer operations. // env.put("jmx.remote.x.access.file", "access.properties"); // Create an RMI connector server. // // As specified in the JMXServiceURL the RMIServer stub will be // registered in the RMI registry running in the local host on // port 3000 with the name "jmxrmi". This is the same name the // out-of-the-box management agent uses to register the RMIServer // stub too. // System.out.println("Create an RMI connector server"); JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:3000/jmxrmi"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); // Start the RMI connector server. // System.out.println("Start the RMI connector server"); cs.start(); } }
Start this application with the following command.
java -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password \ com.example.MyApp
The com.example.MyApp application will enable the JMX agent and will be able to be monitored and managed in exactly the same way as if the Java platform's out-of-the-box management agent had been used. However, there is one slight but important difference between the RMI registry used by the out-of-the-box management agent and the one used by a management agent that mimics it. The RMI registry used by the out-of-the-box management agent is read-only, namely a single entry can be bound to it and once bound this entry cannot be unbound. This is not true of the RMI registry created in Example 2-5.
Furthermore, both RMI registries are insecure as they do not use SSL/TLS. The RMI registries should be created using SSL/TLS-based RMI socket factories which require client authentication. This will prevent a client from sending its credentials to a rogue RMI server and will also prevent the RMI registry from giving access to the RMI server stub to a non-trusted client.
RMI registries which implement SSL/TLS RMI socket factories can be created by adding the following properties to your management.properties file.
com.sun.management.jmxremote.registry.ssl=true com.sun.management.jmxremote.ssl.need.client.auth=true
Example 2-5 mimics the main behavior of the out-of-the-box JMX agent, but does not replicate all the existing properties in the management.properties file. However, you could add other properties by modifying com.example.MyApp appropriately.
Monitoring Applications through a Firewall
As stated above, the code in Example 2-5 can be used to monitor applications through a firewall, which might not be possible if you use the out-of-the-box monitoring solution. The com.sun.management.jmxremote.port management property specifies the port where the RMI Registry can be reached but the ports where the RMIServer and RMIConnection remote objects are exported is chosen by the RMI stack. To export the remote objects (RMIServer and RMIConnection) to a given port you need to create your own RMI connector server programmatically, as described in Example 2-5. However, you must specify the JMXServiceURL as follows:
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:" + port1 + "/jndi/rmi://localhost:" + port2 + "/jmxrmi");
In the URL above, port1 is the port number on which the RMIServer and RMIConnection remote objects are exported and port2 is the port number of the RMI Registry.
Using an Agent Class to Instrument an Application
The Java SE platform provides services that allow Java programming language agents to instrument programs running on the Java VM. Creating an instrumentation agent means you do not have to add any new code to your application in order to allow it to be monitored. Instead of implementing monitoring and management in your application's static main method you implement it in a separate agent class, and start your application with the -javaagent option specified. See the API reference documentation for the java.lang.instrument package for full details about how to create an agent class to instrument your applications.
The following procedure shows how you can adapt the code of com.example.MyApp to make an agent to instrument any other application for monitoring and management.
Creating an Agent Class to Instrument an Application
- Create a com.example.MyAgent class.
Create a class called com.example.MyAgent, declaring a premain method rather than a main method.
package com.example; [...] public class MyAgent { public static void premain(String args) throws Exception { [...]
The rest of the code for the com.example.MyAgent class can be exactly the same as the com.example.MyApp class shown in Example 2-5.
- Compile the com.example.MyAgent class.
- Create a manifest file, MANIFEST.MF, with a
Premain-Class entry.
An agent is deployed as a Java archive (JAR) file. An attribute in the JAR file manifest specifies the agent class which will be loaded to start the agent. Create a file called MANIFEST.MF, containing the following line.
Premain-Class: com.example.MyAgent
- Create a JAR file, MyAgent.jar.
The JAR file should contain the following files.
-
META-INF/MANIFEST.MF
-
com/example/MyAgent.class
-
- Start an application, specifying the agent to provide
monitoring and management services.
You can use com.example.MyAgent to instrument any application for monitoring and management. This example uses the Notepad application.
% java -javaagent:MyAgent.jar -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=password -jar Notepad.jar
The com.example.MyAgent agent is specified using the -javaagent option when you start Notepad. Also, if your com.example.MyAgent application replicates the same code as the com.example.MyApp application shown in Example 2-5, then you will need to provide the keystore and password because the RMI connector server is protected by SSL.


{{define "section"}}
{{.Description}}
Putin · Takeout
{{.Directions}}
Rainchasers is best experienced as an app.


Model railway display destroyed by vandals rebuilt using £107,000 of donations
A model railway exhibition that was destroyed by vandals earlier this year has now been rebuilt thanks to more than £107,000 in donations.
Members of The Market Deeping Model Railway Club had been left in tears after four teenagers trashed the display as part of a ‘pre-exam night out’ earlier this year.
Exhibits which had taken as long as 25 years to make were thrown against walls, smashed and stamped on, including a locomotive unit worth about £8,500.
It has now taken 30 members of the club around 1,000 hours to restore their displays, remaking everything by hand.
The sets are now on display at the Warley Show, at the Birmingham NEC, after a fundraising page was backed by singer Sir Rod Stewart.
Sir Rod donated £10,000 towards the club, telling them he ‘felt their pain’ after taking 23 years to build his his own model railway.
Advertisement Advertisement
Altogether, the page raised more than £107,000 from 5,500 people across the world.
Club chairman Peter Davies, 70, described Sir Rod’s donation as ‘absolutely amazing’, adding that he was pleased to see the club up and running once more.
He said: ‘We could have just easily walked away. That’s not the thing to do, we’re a club, we work together and it’s been satisfying getting it back again.’
Mr Davies previously described how the teenagers had caused ‘total devastation and destruction’ by wrecking the exhibition.
Three 16-year-old boys and one 15-year-old boy had broken into Welland Academy in Stamford, Lincolnshire at around 3.50am on May 18.
They then shared a bottle of vodka, before going on a ‘rampage’, overturning tables and throwing models across the room.
The boys were later found hiding in the toilets after setting off an alarm.
In August, they all admitted criminal damage at Lincoln Youth Court, and three of them were handed 12-month referral orders.
Their parents were also ordered to pay £500 in compensation.
At the time Mr Davies, a grandfather-of-five, said: ‘We are devastated and distraught. It’s heartbreaking.
Advertisement Advertisement
‘There were grown men there in tears because of what had been done, and I admit I was one of them.
‘Can you imagine your life’s work wrecked? One guy spent 25 years on his and it’s wrecked, it’s just horrendous. They left it like a bomb site.
‘There were many different models of locomotives across the hall that were smashed, trodden and kicked about.’
The club have now made a Sir Rod an honorary member and he has his own t-shirt waiting for him to pick up.
The Warley National Model Railway Exhibition, open on Saturday and Sunday, includes 90 model railway layouts and a full-size locomotive display.
Got a story for Metro.co.uk?
Get in touch with our news team by emailing us at<EMAIL_ADDRESS>For more stories like this, check our news page.


Roadmap#
This page describes some of the major medium- to long-term goals for MNE-Python. These are goals that require substantial effort and/or API design considerations. Some of these may be suitable for Google Summer of Code projects, while others require more extensive work.
Page contents
Open#
Time-frequency visualization#
We should implement a viewer for interactive visualization of volumetric source-time-frequency (5-D) maps on MRI slices (orthogonal 2D viewer). NutmegTrip (written by Sarang Dalal) provides similar functionality in Matlab in conjunction with FieldTrip. Example of NutmegTrip’s source-time-frequency mode in action (click for link to YouTube):
Clustering statistics API#
The current clustering statistics code has limited functionality. It should be
re-worked to create a new cluster_based_statistic
or similar function.
In particular, the new API should:
Support mixed within- and between-subjects designs, different statistical functions, etc. This should be done via a
design
argument that mirrorspatsy.dmatrices()
or similar community standard (e.g., this is what is used bystatsmodels.regression.linear_model.OLS
).Have clear tutorials showing how different contrasts can be done (toy data).
Have clear tutorials showing some common analyses on real data (time-freq, sensor space, source space, etc.)
Not introduce any significant speed penalty (e.g., < 10% slower) compared to the existing, more specialized/limited functions.
More details are in #4859.
Access to open EEG/MEG databases#
We should improve the access to open EEG/MEG databases via the
mne.datasets
module, in other words improve our dataset fetchers.
We have physionet, but much more. Having a consistent API to access multiple
data sources would be great. See #2852 and #3585 for some ideas,
as well as:
- Human Connectome Project Datasets
Over a 3-year span (2012-2015), the Human Connectome Project (HCP) scanned 1,200 healthy adult subjects. The available data includes MR structural scans, behavioral data and (on a subset of the data) resting state and/or task MEG data.
- MMN dataset
Used for tutorial/publications applying DCM for ERP analysis using SPM.
- Kymata datasets
Current and archived EMEG measurement data, used to test hypotheses in the Kymata atlas. The participants are healthy human adults listening to the radio and/or watching films, and the data is comprised of (averaged) EEG and MEG sensor data and source current reconstructions.
- BNCI Horizon
BCI datasets.
Integrate OpenMEEG via improved Python bindings#
OpenMEEG is a state-of-the art solver for forward modeling in the field of brain imaging with MEG/EEG. It solves numerically partial differential equations (PDE). It is written in C++ with Python bindings written in SWIG. The ambition of the project is to integrate OpenMEEG into MNE offering to MNE the ability to solve more forward problems (cortical mapping, intracranial recordings, etc.). Some software tasks that shall be completed:
Cleanup Python bindings (remove useless functions, check memory managements, etc.)
Write example scripts for OpenMEEG that automatically generate web pages as for MNE
Understand how MNE encodes info about sensors (location, orientation, integration points etc.) and allow OpenMEEG to be used.
Help package OpenMEEG for Debian/Ubuntu
Help manage the continuous integration system
In progress#
Diversity, Equity, and Inclusion (DEI)#
MNE-Python is committed to recruiting and retaining a diverse pool of contributors, see #8221.
First-class OPM support#
MNE-Python has support for reading some OPM data formats such as FIF, but support is still rudimentary. Support should be added for other manufacturers, and standard (and/or novel) preprocessing routines should be added to deal with coregistration adjustment, forward modeling, and OPM-specific artifacts.
Deep source modeling#
Existing source modeling and inverse routines are not explicitly designed to deal with deep sources. Advanced algorithms exist from MGH for enhancing deep source localization, and these should be implemented and vetted in MNE-Python.
Better sEEG/ECoG/DBS support#
Some support already exists for iEEG electrodes in MNE-Python thanks in part to standard abstractions. However, iEEG-specific pipeline steps (e.g., electrode localization) and visualizations (e.g., per-shaft topo plots, Time-frequency visualization) are missing. MNE-Python should work with members of the ECoG/sEEG community to work with or build in existing tools, and extend native functionality for depth electrodes.
Time-frequency classes#
Our current codebase implements classes related to TFRs that
remain incomplete. We should implement new classes from the ground up
that can hold frequency data (Spectrum
), cross-spectral data
(CrossSpectrum
), multitaper estimates (MultitaperSpectrum
), and
time-varying estimates (Spectrogram
). These should work for
continuous, epoched, and averaged sensor data, as well as source-space brain
data.
See related issues #6290, #7671, #8026, #8724, #9045, and PRs #6609, #6629, #6672, #6673, #8397, and #8892.
Pediatric and clinical MEG pipelines#
MNE-Python is in the process of providing automated analysis of BIDS-compliant datasets, see MNE-BIDS-Pipeline. By incorporating functionality from the mnefun pipeline, which has been used extensively for pediatric data analysis at I-LABS, better support for pediatric and clinical data processing can be achieved. Multiple processing steps (e.g., eSSS), sanity checks (e.g., cHPI quality), and reporting (e.g., SSP joint plots, SNR plots) will be implemented.
Statistics efficiency#
A key technique in functional neuroimaging analysis is clustering brain activity in adjacent regions prior to statistical analysis. An important clustering algorithm — threshold-free cluster enhancement (TFCE) — currently relies on computationally expensive permutations for hypothesis testing. A faster, probabilistic version of TFCE (pTFCE) is available, and we are in the process of implementing this new algorithm.
3D visualization#
Historically we have used Mayavi for 3D visualization, but have faced limitations and challenges with it. We should work to use some other backend (e.g., PyVista) to get major improvements, such as:
Proper notebook support (through ipyvtklink) (complete)
Better interactivity with surface plots (complete)
Time-frequency plotting (complementary to volume-based Time-frequency visualization)
Integration of multiple functions as done in
mne_analyze
, e.g., simultaneous source estimate viewing, field map viewing, head surface display, etc. These are all currently available in separate functions, but we should be able to combine them in a single plot as well.
The meta-issue for tracking to-do lists for surface plotting is #7162.
Documentation updates#
Our documentation has many minor issues, which can be found under the tag #labels/DOC.
Completed#
Distributed computing support#
MNE-BIDS-Pipeline has been enhanced with support for cloud computing via Dask and joblib. After configuring Dask to use local or remote distributed computing resources, MNE-BIDS-Pipeline can readily make use of remote workers to parallelize processing across subjects.
2D visualization#
This goal was completed under CZI EOSS2. Some additional enhancements that could also be implemented are listed in #7751.
Tutorial / example overhaul#
This goal was completed under CZI EOSS2. Ongoing documentation needs are listed in Documentation updates.
Cluster computing images#
As part of this goal, we created docker images suitable for cloud computing via MNE-Docker.


Package com.umidity.cli.frames
Class FrameManager
java.lang.Object
com.umidity.cli.frames.FrameManager
- Direct Known Subclasses:
MainCli
public class FrameManager
extends java.lang.Object
FrameManager is the main character on Form management for the CLI. Best practice suggests to extend this class in order to override "refresh methods".
"Refresh methods" are those executed every "frame update" to perform update actions; more specifically:
1 - init(): executed only the first time refresh() is called. it's suitable for initialization actions.
2 - beforeUpdate(): actions executed before frame update. Suitable for changing the view.
3 - update(): during frame update. Override this to update the view.
4 - afterUpdate(): actions performed after frame update. Suitable for input management.
-
Field Summary
-
Constructor Summary
Constructors Constructor Description FrameManager()
-
Method Summary
Modifier and Type Method Description protected void
__afterUpdate()
Override this only IF you know what you're doingprotected void
__beforeUpdate()
Override this only IF you know what you're doingprotected void
__init()
Override this only IF you know what you're doingprotected void
__update()
Override this only IF you know what you're doingvoid
add(Frame frame)
Add a Frame to the Frame listprotected void
afterUpdate()
override this method to perform actions after the screen updateprotected void
beforeUpdate()
override this method to perform actions before the screen updateprotected static void
clearConsole()
Clear console view Some code is directly taken from StackOverflow, needs revision.Frame
getFrame()
Get first frame in the Frame listFrame
getFrame(java.lang.String name)
Get a Frame in the Frame list which has the given name.protected void
init()
Override this to perform actions one time and never againvoid
refresh()
Refresh viewprotected void
refreshScreen()
For every frame on this FrameManager, call show() method, which will call every show() method on every Form enabled in the Frame.void
remove(Frame frame)
Remove a Frame from the Frame list.void
setPath(java.lang.String newPath)
set a new path for next screen updateprotected void
update()
override this method to perform actions during the screen updateMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Field Details
-
frames
-
inited
protected java.lang.Boolean inited -
path
protected java.lang.String path
-
-
Constructor Details
-
FrameManager
public FrameManager()
-
-
Method Details
-
add
Add a Frame to the Frame list- Parameters:
frame
-
-
remove
Remove a Frame from the Frame list. Usage example: frameManager.remove(frameManager.getFrame("SettingsFrame"));- Parameters:
frame
-
-
getFrame
Get a Frame in the Frame list which has the given name.- Parameters:
name
- name assigned to the Frame at initialization- Returns:
-
getFrame
Get first frame in the Frame list- Returns:
-
refresh
public void refresh()Refresh view -
__init
protected void __init()Override this only IF you know what you're doing -
__beforeUpdate
protected void __beforeUpdate()Override this only IF you know what you're doing -
__update
protected void __update()Override this only IF you know what you're doing -
__afterUpdate
protected void __afterUpdate()Override this only IF you know what you're doing -
init
protected void init()Override this to perform actions one time and never again -
beforeUpdate
protected void beforeUpdate()override this method to perform actions before the screen update -
update
protected void update()override this method to perform actions during the screen update -
afterUpdate
protected void afterUpdate()override this method to perform actions after the screen update -
refreshScreen
protected void refreshScreen()For every frame on this FrameManager, call show() method, which will call every show() method on every Form enabled in the Frame. -
clearConsole
protected static void clearConsole()Clear console view Some code is directly taken from StackOverflow, needs revision. -
setPath
public void setPath(java.lang.String newPath)set a new path for next screen update- Parameters:
newPath
-
-


Conduct Foundational Work
We are building our foundational social and technical infrastructure to enhance our research community's ability to tackle large problems.
Project overview
Wikimedia projects are created and maintained by a vast network of individual contributors and organizations with different roles and expertise. The Wikimedia Foundation, including Wikimedia Research, plays an important role in supporting these efforts, but our internal capacity and expertise will always be more limited than those of the Movement as a whole. Tackling the strategic challenges ahead requires an investment in foundational social and technical infrastructure that individuals, groups, and organizations across the Movement can use.
We see an urgent need for increasing the development and dissemination of foundational resources to grow research capacities across the Movement. These foundational resources take many forms: new tools for developing scientific knowledge about projects and contributors; new open data resources and improved tools for working with them; new methods and guidance for mission-aligned research and technology development; and outreach activities designed to foster a healthy, diverse, and dynamic community of researchers to be part of the Wikimedia Movement.
More information can be found in our white paper and research community vision and strategy.
Recent updates
-
Differential Privacy Data Release
We collaborated with the Security team to release a new, differentially-private dataset of geographic pageview data for the Wikimedia projects. -
Wiki Workshop 2023
The 10th edition of Wiki Workshop is scheduled for May 11, 2023. You are invited to participate. -
From Hell to HTML
We released a new blogpost detailing our work to build a Python library for making the Enterprise HTML dumps more accessible to researchers. -
7th Research Report Released
The report describes what our Research team worked on between June and December 2022. -
2022 Research Fund Grantees Announced
The Wikimedia Foundation's Community Resources and Research teams are excited to announce the 2022 Research Fund grantees! -
Research Community Vision and Strategy
We released our vision and strategy for supporting the network of researchers working on the Wikimedia projects. -
6th Research Report Released
The report describes what our Research team worked on between January and June 2022. -
Python Library for Describing Edits
We developed a new Python library for providing structured summaries of what was changed by edits on Wikipedia. -
Python Library for SQL Dumps
We developed a new Python library for parsing the Wikimedia SQL dumps, which contain rich information about page links and much more.


He is the main vocalist in the group
he is the band leader always incharge of the daily activities of the group members


Click the button to toggle the visibility of the area shown below.
Try this example in both Chrome and Firefox to see differences in the way browsers handle errors.
myForm.input.$valid = {{myForm.numberInput.$valid}}
myForm.input.$error = {{myForm.numberInput.$error}}
myForm.$valid = {{myForm.$valid}}
myForm.$error.required = {{!!myForm.$error.required}}


< WEST WATCHING
INDIGO MOUNTAINS >
In Visione Naturali
+46 722 12 14
+46 (021) 244 84
<EMAIL_ADDRESS>Reserve Your Spot
Download


You can use this section to draft new messages and create new topics
You can view the notices you have published already
| Date | Topic | Title | Message | Expiration time |
|---|---|---|---|---|
| {{ notice.date }} | {{ notice.title }} | {{ notice.topic }} | {{ notice.message }} | {{ notice.expiration }} |


White Birch Resort sits on the northeast corner of beautiful Blackduck Lake which consists of 2,596 acres. With it's natural beauty of overwhelming sunsets, calm summer lake breezes and spectacular views you are sure to receive the best resort lake view on Blackduck Lake.


I'am a hard-working web developer with a flair for creating elegant solutions in the least amount of time. I can developed an ecommerce webapp, customer web portal, documentary launch website, and donations webapp for a local charity. Passionate about software architecture and cloud computing. Regular attendee of web developer meetups and hackathons.
Freelance Web Developer
2021 - 2022
2020-2021: Moringa school
Software Development
| Soft Skills | Hard skills | Programming languages |
|---|---|---|
| Good communication | Git and Github | Html |
| Problem Solving | Debugging | Css |
| Critical Thinking | Figma Design | Javascript |
| Collaboration | Algorithms | Python |


'Quite rough with small gangs': The Newcastle street some people are ashamed to live on
Residents on Stanhope Street in Arthur's Hill have revealed what it is really like to live on the Newcastle street
by Rachael NicholOnce an area where everyone knew their neighbours, residents on this Newcastle street say it has now lost its community spirit.
Riddled by crime and with streets full of litter, Stanhope Street in Arthur's Hill is a shadow of its former self.
Right in the heart of the community lies Hutchinson's Fruit Shop, a family run business that has been open since the 1970s.
One employee at the shop said he has lived on the street most of his life and has seen a big change in the area.
The 32-year-old said: "It was amazing growing up as I knew people around here for years.
"It has changed over the years and now it has become quite rough with small gangs."
Jo Young, who also works at the shop, was born and grew up on the street and is disappointed in how things have changed.
The 42-year-old said: "It’s a bit rough now, it's changed quite a lot.
"There’s a lot of litter down the back lanes, I have to fight my way to get down them."
Home to many traditional and multi-cultural businesses, one resident had happy memories going up on the street.
Joan Ellis, 72, said she had seen huge changes in the area since she moved to the street 45 years ago.
And she admitted that she was heartbroken at how the area had changed.
She said: "I'm actually quite embarrassed about living here. Whenever someone asks where I live I'm ashamed to say.
"When I first moved here it was a lovely place to live. It’s not the same as it used to be, now nobody knows their neighbours.
"People always seem to miss bin day so they end up leaving bin bags out on the street and on the weekend there’s litter everywhere. It’s awful."
However, Stanhope Halal Food Store owner Hamid Muhamad said he is proud of his street.
And he insists that there is still a great sense of community spirit in the area.
Moving to Newcastle from Afghanistan, he used to be a taxi driver before opening his store which has been running for five years.
The 36-year-old said: "I love this area, it is very busy everyone's smiling and are really friendly."
Taxi driver Ansar Quaraishi, who has lived in Arthur's Hill for 30 years, agreed.
The 36-year-old said: "It is still very traditional here but there are a lot more shops now and there is such a great environment.
"I never want to live anywhere else."


The upperparts are dark brown with a white belly with black streaks, the legs are white and has very large talons.
coming soon
The Martial Eagle is to be found in the savannah and thornbush areas of Africa south of the Sahara, from Senegal to Somalia and south to the Cape. It is also found in open plains and semi-desert country, but not frequenting forest, although it occasionally breeds in forests on the edge of open country.
Martial Eagle may hunt as well in flight as from a perch. It does most of its hunting from the soar. It kills or attacks, making a long slanting stoop at great speed, or making a gentle descent into an opening in the bush.
Birds as large as a European Stork are recorded to have fallen prey to the Martial Eagle. In other areas the diet is largely mammalian, especially hyrax and small antelopes. Animals as large as an Impala calf are taken, and some monkeys, also occasionally young domestic goats, and lambs.
THANK YOU


| This inspection reports any instances of tail recursion, that is when a JavaScript function calls itself as its last action before returning. Tail recursion can always be replaced by looping, which will be considerably faster. Some JavaScript engines perform this optimization, while others do not. Thus, tail recursive solutions may have considerably different performance characteristics on different environments. |
| Powered by InspectionJS |


--- layout: page title: About header-img: "img/about-bg.png" ---
Having started my coding journey by learning Swift (iOS) on my own, I'm jump-starting my new coding career through in-depth learning on Flatiron's Full Stack Web Dev program. Having a good deal of experience beforehand, I'm finding some tips and tricks and quirks that the courses leave out, and sharing them with you.


Pedestrian hit by car in Barrhead in rush hour crash
Police and ambulance services rushed to the scene.
by Julie Dunnett, https://www.dailyrecord.co.uk/authors/julie-gilbert/Emergency services rushed to Barrhead in Renfrewshire this morning after a pedestrian was hit by a car.
The accident happened just after 7am this morning.
Police were unable to provide an update on the condition of the person hit.
A spokesperson for Police Scotland said: "We were called at 7.25am this morning to Main Street in Barrhead to a report of a crash involving a car and a pedestrian.
"Ambulance were in attendance."


Back To Index
SMG Howto index
A pre-requisite to follow the howtos is to have a running SMG instance. Easiest is to follow the
- How to Run SMG howto.
How to monitor
- Network switches
- Hosts/Nodes
- Haproxy LB stats
- Nginx status
- Java over JMX
- Mysql
- Redis
- Kafka consumer groups
- Prometheus-style metrics
- “One-off” stats
- Deployments using Configuration Management systems (like Chef or Ansible)
- Kubernetes cluster and services deployed on it


Measuring the weight of an electron
Electrons are small, should be easy. Right?!I am going to “Measure the weight of an electron”! By “weight”, I mean what it takes to make Electron work on OpenBSD.
This is a long rant. A rant intended to document lunacy, hopefully aid others in the future and make myself fell better about something I think is crazy. It may seem like I am making an enemy of electron, but keep in mind that isn’t my intention! The enemy here, is complexity!
My friend Henry, a canary, is coming along for the ride!
Getting the tools
At first glance Electron seems like a pretty solid app, it has decent docs, it’s consolidated in a single repository, has a lot of visibility, porting it shouldn’t be a big deal, right?
First things first, clone that repo!
git clone git@github.com:electron/electron.git
If you want to follow along, we will be using the build instructions for linux doc.
Reading through the doc, right off the bat there are a few interesting things:
- At least 25GB disk space
Huh, OK, some how this ~47M repository is going to blow up to 25G? I glance at Henry, he gives me the “what?” look. We carry on.
- Clang 3.4 or later.
This one isn’t odd until we have more context. More on this one later.
Continuing along with the build, I know I have two versions of clang
installed on OpenBSD, one from ports and one in base. Hopefully I will
be able to tell the build to use one of these versions.
Indeed Electron has that ability! Their example is even using the same prefix OpenBSD’s clang port!
So, we run the bootstrap:
./script/bootstrap.py -v --clang_dir /usr/local
Traceback (most recent call last):
File "./script/bootstrap.py", line 10, in <module>
from lib.config import BASE_URL, PLATFORM, enable_verbose_mode, \
File "/home/qbit/dev/electron_wut/script/lib/config.py", line 17, in <module>
}[sys.platform]
KeyError: 'openbsd6'
Dang. Looks like we need to tell bootstrap about OpenBSD. Easy enough:
diff --git a/script/lib/config.py b/script/lib/config.py
index 58f467b5b..646af08f7 100644
--- a/script/lib/config.py
+++ b/script/lib/config.py
@@ -14,6 +14,7 @@ PLATFORM = {
'darwin': 'darwin',
'linux2': 'linux',
'win32': 'win32',
+ 'openbsd6': 'openbsd',
}[sys.platform]
verbose_mode = False
We re-run the bootstrap, things seem to be going well.. Then the Henry squeaks: “whoa!!”:
Synchronizing submodule url for 'vendor/requests'
git submodule update --init --recursive
Cloning into '/home/qbit/dev/electron_wut/vendor/boto'...
error: object c1eddff4ee3f62b6039f1083651b9118883e7f07: badTimezone: invalid author/committer line - bad time zone
fatal: Error in object
fatal: index-pack failed
fatal: clone of 'https://github.com/boto/boto.git' into submodule path '/home/qbit/dev/electron_wut/vendor/boto' failed
Failed to clone 'vendor/boto'. Retry scheduled
Cloning into '/home/qbit/dev/electron_wut/vendor/breakpad'...
We just failed to clone the boto
repo, but the build is still
going.. does this mean it was an optional dependency and isn’t needed
for the build?
Henry doesn’t look happy, none the less, he assures me it’s OK to go on. What a trooper!
Cloning into '/home/qbit/dev/electron_wut/vendor/requests'...
error: object 5e6ecdad9f69b1ff789a17733b8edc6fd7091bd8: badTimezone: invalid author/committer line - bad time zone
fatal: Error in object
fatal: index-pack failed
fatal: clone of 'https://github.com/kennethreitz/requests' into submodule path '/home/qbit/dev/electron_wut/vendor/requests' failed
Failed to clone 'vendor/requests'. Retry scheduled
Cloning into '/home/qbit/dev/electron_wut/vendor/boto'...
error: object c1eddff4ee3f62b6039f1083651b9118883e7f07: badTimezone: invalid author/committer line - bad time zone
fatal: Error in object
fatal: index-pack failed
fatal: clone of 'https://github.com/boto/boto.git' into submodule path '/home/qbit/dev/electron_wut/vendor/boto' failed
Failed to clone 'vendor/boto' a second time, aborting
Wait. Another repository failed to clone? At least this time the build
failed after trying to clone boto
.. again. I am guessing it tried
twice because something might have changed between now and the last
clone? Off in the distance we catch a familiar tune, it almost sounds
like Gnarls Barkley’s song Crazy, can’t tell for sure.
As it turns out, if you are using git-fsck, you are unable to clone boto and requests. Obviously the proper fix for his is to not care about the validity of the git objects!

I look at Henry, he assures me it’s safe to go on.
We re-run bootstrap… thousands of lines fly past.. “npm
verb... something something
”. I can only think npm is puking this
info for it’s on benefit. It definitely isn’t for ours!
Bah, another error:
subprocess.CalledProcessError: Command '['/usr/local/bin/python', '/home/qbit/dev/electron_wut/vendor/libchromiumcontent/script/download', '-s', '-f', '-c', '94c58176db175d72d88621afe8223b4175eecba5', '--target_arch', 'x64', 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent', '/home/qbit/dev/electron_wut/vendor/download/libchromiumcontent']' returned non-zero exit status 1
Looks like it’s trying to download a pre-built libchromiumcontent
,
we reference the doc again, finding the --build_libchromiumcontent
option. Re-run!
This time we are faced with .
’s, I have no idea what is happening:
/usr/local/bin/python /home/qbit/dev/electron_wut/vendor/libchromiumcontent/script/update -t x64 --defines make_clang_dir=/usr/local clang_use_chrome_plugins=0
.......
Looking in top
, we can see a python process with a WAIT of netio
,
maybe it’s downloading something? Looking in the electron_wut
directory reveals a growing file named
chromium-58.0.3029.110.tar.xz
. We let it finish downloading.
Out of curiosity we look at vendor/libchromiumcontent/script/update
,
it seems its purpose is to download / extract chromium clang and node,
good thing we already specified --clang_dir
or it might try to build
clang again!
544 dots and 45 minutes later, we have an error! The
chromium-58.0.3029.110.tar.xz
file is mysteriously not there
anymore.. Interesting.
Scrolling up in the terminal points us to something disheartening:
Extracting...
Updating Clang to 296320-1...
Creating directory /home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/third_party/llvm-build
Traceback (most recent call last):
File "/home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/tools/clang/scripts/update.py", line 902, in <module>
sys.exit(main())
File "/home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/tools/clang/scripts/update.py", line 898, in main return UpdateClang(args)
File "/home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/tools/clang/scripts/update.py", line 420, in UpdateClangi assert sys.platform.startswith('linux')
AssertionError
None
Wut. “Updating Clang…”. Didn’t I explicitly say not to build clang?
At this point we have to shift projects, no longer are we working on
Electron.. It’s libchromiumcontent
that needs our attention.
Fixing sub-tools
git clone git@github.com:electron/libchromiumcontent.git
Following the
instructions on this
repo, we run script/bootstrap
.. it seems to complete without issue!
On to the next steps:
script/update -t x64
Ahh, our old friends the dots! This is the second time waiting 45+
minutes for a 500+ MB file to download. We are fairly confident it
will fail, delete the file out from under itself and hinder the
process even further, so we add an explicit exit to the update
script. This way we can copy the file somewhere safe!
diff --git a/script/update b/script/update
index 234e4b3..b2639bf 100755
--- a/script/update
+++ b/script/update
@@ -107,6 +107,7 @@ def download_source_tarball(version):
sys.stderr.flush()
t.write(chunk)
+ sys.exit()
sys.stderr.write('\nExtracting...\n')
sys.stderr.flush()
544 dots and 43 minutes later…. chromium-58.0.3029.110.tar.xz
is
safe!
Fool me once…
mkdir safe_space
cp chromium-58.0.3029.110.tar.xz safe_space/
We remove the sys.exit()
and re-run! Wut.. dots again!? Lets look
deeper into this update
script:
if not args.no_download:
version = chromium_version()
if not is_source_tarball_updated(version):
download_source_tarball(version)
else:
print "Skipping Chromium Source Tarball Download"
Ok, lets try that.. We copy the tar.xz out of its safe_space…
Skipping Chromium Source Tarball Download
Traceback (most recent call last):
File "/home/qbit/dev/libchromiumcontent/vendor/python-patch/patch.py", line 1136, in <module>
patch.apply(options.strip, root=options.directory) or sys.exit(-1)
File "/home/qbit/dev/libchromiumcontent/vendor/python-patch/patch.py", line 778, in apply
os.chdir(root)
OSError: [Errno 2] No such file or directory: '/home/qbit/dev/libchromiumcontent/src/.'
Sigh. The above (or similar) was repeated about 50 times… The trend here seems to be: Ignore errors!
Since def download_source_tarball
should actually be def
download_source_tarball_then_extract
, we do that part for
it… and pat ourselves on the back for having a safe_space
!
As chromium extracts, Henry and I can’t shake the feeling that everything until now was just the tip of the iceberg
We remove the call to update_clang
, because.. well.. we have two
copies of it already and the Electron doc said everything would be fine
if we had >= clang 3.4!
Re-run..
already patched third_party/WebKit/Source/core/paint/ThemePainterMac.mm
already patched third_party/WebKit/Source/platform/mac/KillRingMac.mm
qbit@slip[1]:libchromiumcontent[master *%=]λ
That [1]
in my PS1 means that the update script exited with the
return code 1
… but there is no indication of why..
Henry’s lovely yellow plumage seems to be becoming a darker shade of yellow.. How much more of this can we take?!
If we have learned anything so far, it has to be “errors don’t matter!”. This one, however, warrants further investigation!
We dig deeper into script/update
update_gn()
.. pulls down a binary gn
.. which, interestingly, can
be generated with the code we have right below our feet… but for
some reason, they have this component already built. There is no
pre-built version for OpenBSD.
At this point, Henry and I are getting pretty irritated.. it’s time to bring in some big guns! We are going to leverage the countless hours of work that have already been put into properly building these components! (novel, right?!)
We quickly move to /usr/ports/www/chromium
, low and behold, it’s the
exact version that libchromiumcontent
is trying to build! We
review the Makefile
to find this gem: 2. bootstrap gn, the tool to
generate ninja files
Running make configure
quickly gets us a usable gn
binary, we make
the appropriate directories under src/buildtools, copy gn
in, modify
our script/update
file:
diff --git a/script/update b/script/update
index 234e4b3..b5c4afc 100755
--- a/script/update
+++ b/script/update
@@ -52,9 +52,9 @@ def main():
return (apply_patches() or
copy_chromiumcontent_files() or
- update_clang() or
- update_gn() or
- update_node() or
+ #update_clang() or
+ #update_gn() or
+ #update_node() or
run_gn(target_arch, args.defines))
@@ -248,6 +248,8 @@ def run_gn(target_arch, defines):
gn = os.path.join(SRC_DIR, 'buildtools', 'linux64', 'gn')
elif sys.platform == 'darwin':
gn = os.path.join(SRC_DIR, 'buildtools', 'mac', 'gn')
+ elif sys.platform == 'openbsd6':
+ gn = os.path.join(SRC_DIR, 'buildtools', 'openbsd', 'gn')
env = os.environ.copy()
if sys.platform in ['win32', 'cygwin']:
Re-run!
ERROR at //build/config/sysroot.gni:95:5: Assertion failed.
assert(
^-----
Missing sysroot (//build/linux/debian_wheezy_amd64-sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=amd64
See //build/config/sysroot.gni:96:9:
exec_script("//build/dir_exists.py",
^-----------------------------------
Wheezy?! Where is that getting set?!  What could have possibly warranted abandoning makefiles and shell scripts in favor of this monstrosity!?
Just for fun.. lets try to run the second step (after all, the first
step only produced a 1
, right!?)
script/build -t x64
FML:
qbit@slip[1]:libchromiumcontent[master *%=]λ script/build -t x64
Unsupported OS OpenBSD
No prebuilt ninja binary was found for this system.
Try building your own binary by doing:
cd ~
git clone https://github.com/martine/ninja.git -b v1.7.2
cd ninja && ./configure.py --bootstrap
Then add ~/ninja/ to your PATH.
Traceback (most recent call last):
File "script/build", line 57, in <module>
sys.exit(main())
File "script/build", line 43, in main
subprocess.check_call([NINJA, '-C', os.path.relpath(out_dir), target], env=env)
File "/usr/local/lib/python2.7/subprocess.py", line 186, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/home/qbit/dev/libchromiumcontent/vendor/depot_tools/ninja', '-C', 'src/out-x64/static_library', 'chromiumcontent:chromiumcontent']' returned non-zero exit status 1
qbit@slip[1]:libchromiumcontent[master *%=]λ which ninja
/usr/local/bin/ninja
qbit@slip[0]:libchromiumcontent[master *%=]λ
Clearly we are dealing with a beast that is too smart for its own good.
Fixing sub-sub-tools
Since depot_tools
is a Google project, it’s easier to edit the files
in the vendor
directory and pretend nothing ever happened.
diff --git a/ninja b/ninja
index 282cc276..e22cbb9a 100755
--- a/ninja
+++ b/ninja
@@ -37,7 +37,5 @@ case "$OS" in
Darwin) exec "${THIS_DIR}/ninja-mac" "$@";;
CYGWIN*) exec cmd.exe /c $(cygpath -t windows $0).exe "$@";;
MINGW*) cmd.exe //c $0.exe "$@";;
- *) echo "Unsupported OS ${OS}"
- print_help
- exit 1;;
+ *) exec "/usr/local/bin/ninja" "$@";;
esac
Sigh. So many assumptions, lets continue the trend!
cd ../../
Re-run script/build -t x64
…
No luck. At this point we are faced with a complex web of python
scripts that execute gn
on GN files to produce ninja files… which
then build the various components and somewhere in that cluster,
something doesn’t know about OpenBSD…
I look at Henry, he is looking a photo of his wife and kids. They are sitting on a telephone wire, the morning sun illuminating their beautiful faces. Henry looks back at me and says “It’s not worth it.”


Summary and History
STARS (Students, Technology, Academics, Research, and Service) Computing Corps is a national alliance of colleges and universities with a mission to develop college students and faculty as leaders who broaden participation of women, underrepresented minorities, and persons with disabilities in computing. STARS student members take an active role in broadening participation in computing and develop their technical skills by leading service learning projects, including near-peer outreach that introduces K-12 students to computing as well as within-department peer tutoring, mentoring, and research collaborations. Since 2006, over 2600 STARS students and 80 faculty across 53 academic institutions have reached more than 140,000 K-12 students in STARS outreach programs. STARS Computing Corps @ Temple University was founded in the fall of 2018, and we started by hosting a few technical workshops and partnering with the Philadelphia Military Academy in the spring of that year. Since then, we’ve grown to teaching two AP Computer Science classes, hosting several workshops per semester, giving technical presentations to Philadelphia schools, and more. Follow our website and social media to see how we continue to grow and work to broaden participation in computing!
What We Do
STARS Computing Corps @ Temple University has three pillars of computer science engagement for secondary students: workshops, demonstrations, and teaching. Each semester, our volunteers design a handful of free workshops surrounding current topics in computing and technology. This might include web application development, micro-computer (Arduino, Micro::bit, RaspberryPi) programming, and more. We use our computer labs in the Temple University Science Education and Research Center to provide students with all of the equipment and other resources needed to succeed in the workshops. Topics are driven by feedback from students, and our members’ interests. These workshops are meant to provide a creative outlet and learning experience for students, with the hopes of encouraging them to work in or study computer science, or a related field. Throughout the school year, STARS Computing Corps @ Temple University visits schools in the Philadelphia School District to give presentations on topics in computer science. Typically, we present to an individual class at a time, rather than an entire school; this lets us tailor our presentation, and gives students more opportunity to ask questions. In the past, our volunteers have presented on machine learning, 3D printing, and robotics. We try to align presentation topics with upcoming workshops so that students have the opportunity to follow up and get hands on experience. We partner with schools and academic organizations to provide computer science teaching to high school students in Philadelphia. On Temple University’s campus, we work with the Steppingstone Scholars program to teach their after-school Java programming course, where our volunteers design and teach a curriculum that draws from AP Computer Science A as well as Oracle’s Java SE 8 Programmer I exam. Our volunteers provide feedback on the students’ programming projects, outside of class time. We also partner with the nearby Philadelphia Military Academy to assist in teaching their AP Computer Science Principles class on a daily basis. At PMA, we help lecture and lead students through in-class activities.


DALI @ MICCAI
Home
Important Dates
Call For Papers
Program
People
Previous Editions
MIL3D
LABELS
404
Page not found :(
The requested page could not be found.