Wednesday, March 31, 2021

sql logging for jsf application in netbeans

To enable SQL logging to the netbeans console for a JSF application running in Payara with EclipseLink, add the following properties to the persistence.xml file: 
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.logger" value="DefaultLogger"/>
More information here and here.

On a related note, logging can also be enabled directly in mysql, if that's the underlying database.  Here are some notes about doing that:

log in to mysql as root:
-> use mysql; 
-> SET global log_output = 'table'; 
-> SET GLOBAL general_log = 1;
then you can see the logged statements using:
select * from general_log;

or count the number of sql statements:
select count(*) from general_log; 
and clean it up with:
truncate general_log; 

Friday, March 12, 2021

java method reference

I can never remember the syntax for passing a method reference in Java, so I'm pasting a note about it here.  Here is a decent link explaining the idea.

Here is a method that accepts a method reference as a parameter, and calls that method in its body:

protected ItemDomainEntity findByPath_(String path, Function<ItemDomainEntity, ItemDomainEntity> parentGetterMethod) {

    ItemDomainEntity candidateParent = parentGetterMethod.apply(candidateItem);


And then an example of calling that method:

findByPath_(path, ItemDomainMachineDesign::getParentMachineDesign);

Tuesday, February 2, 2021

dynamic datatable components in primefaces

I'm making notes about this here for future reference. I have an JSF application where I'm using a primefaces datatable component. 

One thing that I don't love about the current approach is that the rows in the table are domain objects in the application, and each column therefore must be a property of the object in order to display the column values. Some of the columns I want to display in the table are not naturally properties of the underlying domain object, but just temporary values associated with the task at hand. So to add them as table columns, I have to define them as properties of the object and I don't always like that. 

 More than once I've wondered if it would be better to just use a list of strings as each row in the table. This way, some of the columns might map to properties of the domain object, while others are temporary task-specific values. Anyway, I'm stashing a couple of notes here about how to do this in case I want to experiment with it later. 

Here is a snippet for displaying lists of strings as the rows for the datatable based on this thread

                            <p:dataTable id="#{rootViewId}TableContent"

                                <p:columns value="#{wizardController.rows[0]}" var="column" columnIndexVar="i">

And here is a second thread for displaying dynamically selected columns. This still uses properties on the domain object, but I wonder if I could retrieve the values from some sort of map associated with the domain object instead? Here is a snippet of the view components from that thread: 

    <p:selectCheckboxMenu value="#{employeeBean.selectedColumns}"
                          label="Table Columns">
        <f:selectItems value="#{employeeBean.columnMap.entrySet()}"

        <p:ajax event="change" update="table"/>

    <p:dataTable id="table" var="emp" value="#{employeeBean.employeeList}">
        <p:columns value="#{employeeBean.selectedColumns}" var="colKey">
            <f:facet name="header">
                <h:outputText value="#{employeeBean.columnMap[colKey]}"/>
            <h:outputText value="#{emp[colKey]}"/>
And the corresponding bean code:
public class EmployeeBean {
    private List<String> selectedColumns = new ArrayList<>();
    private List<Employee> employeeList = new ArrayList<>();
    private Map<String, String> columnMap = new LinkedHashMap<>();

    private void postConstruct() {

    private void initColumnProperties() {
        addColumn("id", "ID");
        addColumn("name", "Name");
        addColumn("phoneNumber", "Phone Number");
        addColumn("address", "Address");

    private void addColumn(String propertyName, String displayName) {
        columnMap.put(propertyName, displayName);

    private void initEmployeeList() {
        DataFactory dataFactory = new DataFactory();
        for (int i = 1; i < 20; i++) {
            Employee employee = new Employee();
            employee.setPhoneNumber(String.format("%s-%s-%s", dataFactory.getNumberText(3),
            employee.setAddress(dataFactory.getAddress() + "," + dataFactory.getCity());

    public List<Employee> getEmployeeList() {
        return employeeList;

    public List<String> getSelectedColumns() {
        return selectedColumns;

    public void setSelectedColumns(List<String> selectedColumns) {
        this.selectedColumns = selectedColumns;

    public Map<String, String> getColumnMap() {
        return columnMap;

Friday, November 27, 2020

re-installing MacOS on macbook with bad OS install

We had a laptop that was in a bad state after a failed OS upgrade. It was trying to autoboot to the installer, but the installer claimed that the macbook didn't support that OS version. After looking up the valid latest OS version for the macbook, I followed the instructions in this macworld article to load a MacOS installer on a thumb drive and install MacOS on the broken macbook. I chose to format (erase) the hard drive using disk utility before installing MacOS.

Friday, April 24, 2020

merge latest from main git repo to my fork

This works better than a web-gui initiated pull request when there are conflicts that must be resolved manually. From this link:
# First add the upstream remote:

git remote add upstream https://repoA
git fetch upstream

# Merge in upstream changes:

git checkout master
git merge upstream/master

# Resolve conflicts and push:

git push origin master

# Your pull request should automatically update

Monday, April 6, 2020

skypeforlinux fails to run due to wrong version of libstdc++

Once again skypeforlinux fails to run, this seems to be a weekly occurrence for me. Not sure why it's so fragile. Usually it's due to the permissions problem that I documented a couple of months ago. This time, it's not finding the correct version of libstdc++. I updated the OS and installed anaconda last week, so I'm guessing it's due to one of those actions.

The error message looked like this:
$ /usr/share/skypeforlinux/skypeforlinux
A JavaScript error occurred in the main process
Uncaught Exception:
Error: /lib64/ version `GLIBCXX_3.4.21' not found (required by /usr/share/skypeforlinux/resources/app.asar.unpacked/node_modules/electron-utility/build/Release/electron_utility.node)
at process.func (electron/js2c/asar.js:140:31)
at process.func [as dlopen] (electron/js2c/asar.js:140:31)
at Object.Module._extensions..node (internal/modules/cjs/loader.js:922:18)
at Object.func (electron/js2c/asar.js:140:31)
at Object.func [as .node] (electron/js2c/asar.js:149:18)
at Module.load (internal/modules/cjs/loader.js:735:32)
at Module._load (internal/modules/cjs/loader.js:648:12)
at Module._load (electron/js2c/asar.js:717:26)
at Function.Module._load (electron/js2c/asar.js:717:26)
at Module.require (internal/modules/cjs/loader.js:775:19)

I found this link, and followed some instructions about using the libstdc++ installed under anaconda in the /usr/lib64 directory. Here is a summary of the steps:

strings /usr/lib64/ | grep GLIBCXX # to see the version of libstdc++ in your lib directory
sudo yum install libstdc++ # does nothing, yum says the package is up to date
sudo find / -name "*" # find other installations of libstdc++, including anaconda
sudo cp /home/craig/anaconda3/lib/ /usr/lib64/ # install libstdc++ from anaconda pkg to lib directory
sudo sudo mv /usr/lib64/ /usr/lib64/ # make a backup of existing lib
sudo ln -s /usr/lib64/ /usr/lib64/ # make symlink for new lib

Friday, April 3, 2020

growing virtualbox guest centos7 linux VM on windows 10 host

Here's another thing that was a whole lot harder than it seems like it should have been. I found several threads/links that were ALMOST everything I needed to know, but missing a couple of important details that probably weren't relevant to the author's situation so not in their process.

This link is very helpful (and this one) and basically describes the correct process.

The details that were missing from the first link were:

1. modifyhd must be done for each snapshot in the VM, not just the main vdi itself (see this link):

To list all the virtualbox drives, use "c:\Program Files\Oracle\VirtualBox>VBoxmanage list hdds". Then for each one associated with the vm you are growing, use modifyhd: "c:\Program Files\Oracle\VirtualBox>VBoxmanage modifyhd "C:\Users\auto\VirtualBox VMs\craigmcc APS dev\Snapshots\{4841ac14-4e09-4b0b-aa54-9665bb1bd4b3}.vdi" --resize 50000". So in my case I used modifyhd 5 times:

c:\Program Files\Oracle\VirtualBox>VBoxmanage modifyhd "C:\Users\auto\VirtualBox VMs\craigmcc APS dev\craigmcc APS dev 20200306 1620-disk001.vdi" --resize 50000

c:\Program Files\Oracle\VirtualBox>VBoxmanage modifyhd "C:\Users\auto\VirtualBox VMs\craigmcc APS dev\Snapshots\{97e89522-0465-4f68-bfa9-ca33d790a379}.vdi" --resize 50000

c:\Program Files\Oracle\VirtualBox>VBoxmanage modifyhd "C:\Users\auto\VirtualBox VMs\craigmcc APS dev\Snapshots\{9eb0ae2e-6b3a-41ba-a212-3c27410d8dbf}.vdi" --resize 50000

c:\Program Files\Oracle\VirtualBox>VBoxmanage modifyhd "C:\Users\auto\VirtualBox VMs\craigmcc APS dev\Snapshots\{6b89d87f-f0d2-4a10-a64a-0b22fdde66de}.vdi" --resize 50000

c:\Program Files\Oracle\VirtualBox>VBoxmanage modifyhd "C:\Users\auto\VirtualBox VMs\craigmcc APS dev\Snapshots\{4841ac14-4e09-4b0b-aa54-9665bb1bd4b3}.vdi" --resize 50000

2. after using "lvextend" you must use "xfs_growfs" to make the space available (this is mentioned in the 2nd link above, but not the first.

After running lvextend, "lsblk" output looked correct, but "df -h" did not show the newly available space. I fixed this by running "sudo xfs_growfs /dev/mapper/centos-root". Now df shows the correct output.

So in a nutshell here are the steps:

1. make the disk partition larger, I used the command line tools shown above whereas the first link does so in vbox manager. "df" doesn't show the available space at this point, unlike the example in the first link above where df does show the space. But gparted does see it...
2. download gparted .iso file
3. mount the .iso file under the vm's storage tab on settings under IDE controller, make sure on system tab that optical is before hard disk in boot order
4. start the vm and run gparted, add the unallocated space to the partition you want to grow (in my case where / is mounted)
5. i had to follow the special LVM instructions in the first link, so in gparted you must "deactivate" the partition with the lock icon before growing it
6. unmount optical disk for gparted and reboot vm
7. display physical volumns with "sudo pvs", should show new free space
8. grow the physical volume with "sudo pvresize /dev/sda2"
9. "lsblk" still shows that the root partition is not using the entire available free space
10. run "sudo lvextend -l +100%FREE /dev/centos/root" to use the entire free space for the logical volume
11. run "sudo xfs_growfs /dev/mapper/centos-root" to grow the logical volume while mounted