Friday, January 9, 2026

The Trig I Never Knew

I learned geometry many decades ago. 

I learned the formulas for the trigonometric functions.

They never made sense to me.

I knew what a tangent was. Why was it also sin/cos?

What was a secant, anyway?

My first realization was π. I thought I knew π. I knew the formulas for the circumference and the area of a circle. I didn't know that the formula for circumference was actually the definition of π.

First came the desire to know the circumference of a circle given the diameter. Second came the realization that it was always the ratio 3.14159265... Third came the name for the ratio, π.

My next realizations were for the trig functions. Where did they originate?

They originated with triangles and the pythagorean theorem. If two sides of the triangle are known, then the third side is known. 

Some basic triangles were needed that could be scaled to other triangles. The basic framework was the unit circle. A circle whose center was the origin of the x-y coordinate system with radius 1. A radius of 1 is used to create simple formulas.

A tangent is a line that intersects the circle in exactly one point.

A secant is a line that intersects the circle in two points. Only the part of the secants that are in the first quadrant will be drawn here. 

Draw a secant with angle θ from the origin to a point outside the circle, in the first quadrant.

Drop a vertical line to the x-axis from the point where the secant intersects the circle.

Draw another secant from the origin to a point outside the circle with an angle 90-θ.

The angle will be called θ. The complimentary angle is 90-θ.

Create a vertical tangent line at x=1.



Trigonometric functions.

The point where the secant crosses the circle defines sin θ and cos θ.

All we really need is sin, since cos θ = sin (90 - θ)

The point where the secant crosses the tangent line is the definition of tan.

By using similar triangles, the ratio of the sin θ / cos θ is the same as the ratio of tan θ / 1.

tan θ = sin θ / cos θ

The intersection of the complimentary secant and the circle is not in the diagram, but it would have coordinates (sin θ, cos θ) and its intersection with the tangent line would be (1, cot θ). 

cot θ = cos θ / sin θ

The length of the secant line from the origin to the tangent line is the definition of sec.

Using the pythagorean theorem on the triangle in the circle gives the identity that sin² θ + cos² θ = 1.

Using the distance formula yields the formula for sec in terms of cos.

First, calculate the square of the sec.

sec² θ = (tan θ - 0)² + (1 - 0)² = tan² θ + 1 = sin² θ / cos ² θ + 1 = (sin² θ + cos² θ) / cos ² θ = 1 / cos ² θ

Then take the square root.

sec θ = 1 / cos θ

A similar calculation with the complement yields

csc θ = 1 / sin θ



Thursday, June 11, 2020

Initializing git repo and setting remote

I have been creating a lot of git repos recently. I am tired of looking up the same information again and again.

I have been creating a lot of Java projects as I experiment with Spring Boot. After creating a repo, I experiment with it a bit, then decide if I want to keep working in it.

The first step is to change to the project directory and and a .gitignore file. I have been using Java on a Mac and this is the file I use.

HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/
 
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# Mac OS $
.DS_Store


Execute git init in the project folder. This creates the .git folder that is the local repo.

I am using GitHub to store remote copies of the repo. Create a new, empty repo and issue the commands:

git commit -m "first commit"
git remote add origin https://git-username@github.com/git-username/git-repo.git
git push -u origin master
 
After these commands, I can use git push to commit changes.

Monday, June 8, 2020

Creating webapp using Spring Boot and Maven

I created a base Spring Boot project to see all the dependencies I needed for a simple web application.

I created a simple Spring Boot project using the Initializr. It had no extra packages added.

I added the spring-boot-starter-web package, which included tomcat. Tomcat had type 'provided'. If I omitted the version, the war did not work when deployed, but worked locally.

I created a simple home controller using the Controller annotation and the GetMapping annotation.

The default view resolver is to the /src/main/resources/static folder without an extension. I created home.html in the static package and the page was found. Static is copied to WEB-INF/classes.

I wanted to deploy the app to an external tomcat installation. I extended the application class from SpringBootServletInitializer to create a war file and identify the starting application.

I added a view resolver and set the view class to JSTL. I had to add a dependency for jstl. I had to add a webapp folder for the JSPs, /src/main/webapp. The path is to the root of the web app. I did not want my JSPs in the classes folder.

Be sure that the path to the JSTL library is http and not https.

These are all the updated files to get it working:

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }             
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
           return application.sources(DemoApplication.class);
        }
        
        @Bean
        public ViewResolver internalResourceViewResolver() {
            InternalResourceViewResolver bean = new InternalResourceViewResolver();
            bean.setViewClass(JstlView.class);
            bean.setPrefix("/WEB-INF/jsp/");
            bean.setSuffix(".jsp");
            return bean;
        }

}

pom.xml


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.0.RELEASE</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>9.0.35</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
index.jsp

<%-- 
    Document   : index
    Created on : Jun 8, 2020, 1:01:38 PM
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

    <c:choose>
        <c:when test="${not empty param.name}">
            <h1>Hello ${param.name}</h1>
        </c:when>
        <c:otherwise>
            <h1>Hello Stranger</h1>
        </c:otherwise>
    </c:choose>
    
</body>
</html>



Wednesday, June 3, 2020

HttpClient Daemon Threads

I have discovered that java.net.http.HttpClient.send leaves daemon threads that do not terminate when interrupted.

I am using
  • Maven 1.6
  • Java 1.14
  • NetBeans 11.3
When I make a simple HTTP request using HttpClient.send using the maven goal exec.java, the code runs, but pauses and I get these warnings after 15 seconds, and then the app stops:

thread Thread[HttpClient-1-Worker-0,5,org.sonatype.mavenbook.ch07.simple.weather.oauth.lone.WeatherYdnJava] was interrupted but is still alive after waiting at least 14997msecs
thread Thread[HttpClient-1-Worker-0,5,org.sonatype.mavenbook.ch07.simple.weather.oauth.lone.WeatherYdnJava] will linger despite being asked to die via interruption
thread Thread[HttpClient-1-Worker-1,5,org.sonatype.mavenbook.ch07.simple.weather.oauth.lone.WeatherYdnJava] will linger despite being asked to die via interruption
thread Thread[HttpClient-1-Worker-2,5,org.sonatype.mavenbook.ch07.simple.weather.oauth.lone.WeatherYdnJava] will linger despite being asked to die via interruption
NOTE: 3 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=org.sonatype.mavenbook.ch07.simple.weather.oauth.lone.WeatherYdnJava,maxpri=10]


It is interesting that if I use the Play button in NetBeans to run the code, it works without any warnings. NetBeans uses exec:exec instead of exec:java. One difference between exec:java and exec:exec is how daemon threads are handled. With exec:java, after maven is done doing its work, maven sends an interrupt to all the daemon threads, hoping that they will terminate nicely. The exec:java goal also runs the code in the same VM as maven.

The exec:exec goal does not show the warning. I do not know the reason, but it could be that it terminates the threads unceremoniously or it waits for them to finish.

Some properties for the exec:java goal control how daemon threads are handled.
  • daemonThreadJoinTimeout - if I set this to 60 seconds or more, then the daemon threads terminate on there own. I assume that the TCP connection was closed by one side, so the threads terminate.
  • cleanupDaemonThreads - if this is set to false, then the threads are not interrupted and the timeout is not used. I assume that the threads are killed.
  • stopUnresponsiveDaemonThreads - this is a bad idea for this example. If I set this to true, the app will never end. As soon as one is killed, another pops up in its place. I assume this would continue for a minute in this case, waiting for the TCP connection to close.
Conclusion: I will use exec:exec. The downside of using exec:exec is that it creates a separate VM to run the java program. If that becomes a problem, I will set cleanUpDaemonThreads to false in the exec:java goal.

Friday, May 22, 2020

Struggling with Nested Tables and Unit Tests

I am using Spring Boot with Spring Data and attempting to write unit tests.

I have a three tables: Orders have more than one Taco. Tacos have more then one ingredient.

I am attempting to read an Order, with all its Tacos, and the Ingredients for each Taco.

In Order, tacos is a list. In Taco, ingredients is a list.

Here are some good references:
JPQL queries. https://www.objectdb.com/java/jpa/query/jpql/from
EntityGraphs: https://www.radcortez.com/jpa-entity-graphs/
Problems with EntityGraphs: https://stackoverflow.com/questions/31943989/spring-data-jpa-and-namedentitygraphs
JPA LifeCycle: https://www.javabullets.com/jpa-entity-lifecycle/
Baeldung EntityGraph example: https://www.baeldung.com/jpa-entity-graph
Removing old data from cache when testing: https://stackoverflow.com/questions/19057802/junit-hibernate-testing-lazy-associations-fetched
Transactional testing: https://www.marcobehler.com/2014/06/25/should-my-tests-be-transactional 

I have tried many ways to complete the task. The most fruitful was with EntityGraph.

When I attempted the query, I received a Hibernate multiple bag exception.

I researched many articles on the net. One solution is to use a set, but one site cautioned against that, since it must create a Cartesian product of all the tables.
https://vladmihalcea.com/hibernate-multiplebagfetchexception/

I tried to follow the advice, but my example is a little different. I believe the example uses the same approach as nested select statements. I cannot use that idea, since that example is accessing two collections from the same parent table. I want to get all tacos for an order, then get all ingredients for each of those tacos. I cannot perform a join on tacos.ingredients, since tacos is a list. I would have to join on the elements in the list.

I am beginning to think that the best solution is to change to sets instead of lists. Without it, I am forced to do a separate select to get the ingredients for each taco and then add those ingredients to the original result set of the tacos in the order.

Here is a new thought: read all the tacos with their ingredients. Somehow, organize these tacos into orders. Bad idea.

I imagine there is no other way than creating the Cartesian product. I will try with sets.

I attempted to work with sets. The changes were minimal, since many of the methods return Iterable.

I used an EntityGraph with a subgraph for ingredients, but it failed with a null pointer exception.

@NamedEntityGraph(
    name = "Taco_Order.detail",
    attributeNodes = {
        @NamedAttributeNode(value="tacos"
                            ,subgraph="tacos-subgraph"
        )
    }
    ,subgraphs = {
        @NamedSubgraph(
            name="tacos-subgraph",
            attributeNodes= {
                @NamedAttributeNode("ingredients")
            })
    }
    )

If I removed the subgraph, it worked, it even retrieved the ingredients. Confusing.

I removed the entity graph and debugged the code. The tacos were not loaded, as was expected.

I will add the entity graph again and see what happens. It may be a case of stale data in the session. I still got the ingredients. I had added an eager findById to taco, maybe that caused a problem.

I am stuck. I do not know why the ingredients are read.






Tuesday, May 5, 2020

Observations about CHtml::link and regular links

I am using Yii and have links to several controllers.

I had normal links in the page that worked when I proceeded from the base URL. They failed after I clicked the Home button in the menu.

After clicking Home, the URL was .../index.php/site/index, referencing the site controller.

When I click the normal link,

   
  • Unit


  • it tries to access .../index.php/site/Unit and fails.

    When I click the CHtml::link in any of these formats,

       

  •    

  •    


  • it tries to access .../index.php/Unit/index and succeeds.

    When I click the modified CHtml::link,

       


  • it tries to access .../index.php/site/Unit/index and fails.

    The only one that works properly is the CHtml::link with an array for the destination URL.

    The normal URLs add to the existing URL, without noticing that index.php is the actual page and the rest of the URL is path info, so they fail.

    Looking at normalizeUrl and createUrl explain the reasons for the CHtml::links.

    • normalizeUrl is only called if the parameter is an array
    • $this->getId() returns the name of the current controller
    • $this->getAction()->getId() returns the name of the action for the current controller
    • The remaining items are from createUrl:
      • If the route parameters is empty, return the current URL
      • If the route does not contain a /, then replace the current action with / and the route
      • If the leading character in the route is not / and the current module is not null, then replace the current controller with the module and add the route
      • If the route has a site/action or /site, then create the URL from the Yii app, not the current controller
    Conclusion, when creating a link for a different controller, use CHtml::link with an array parameter so that the URL is created based on the Yii app and not the current controller.



      Monday, May 4, 2020

      Yii CActiveRecord Relation to a Relation that is a View

      I have tables for Council, Unit, Offices, CouncilOffices, and ViewWithPhonebook. The view is the records for the unit with additional data retrieved from an online phonebook.

      CouncilOffices implements a many-to-many relationship between Offices and Council. The council are unit members who hold offices in the organization.

      Council Relations

      array(
      'officeRelation'=>array(self::MANY_MANY, 'Offices', 
                                    'council_offices(council_index, offices_index)'
      ), 
      'viewRelation'=>array(self::BELONGS_TO,
                  'ViewPhonebook', 'id'),

      'unitRelation'=>array(self::BELONGS_TO, 
                  'Unit', 'id'),       
      );

      CouncilOffices Relations

      array(
          'councilRelation'=>array(self::BELONGS_TO, 
                                   'Council', 'council_index'),
          'officesRelation'=>array(self::BELONGS_TO, 
                                   'Offices', 'offices_index'),
      );

      Offices Relations

      array(
           'councilRelation'=>array(self::MANY_MANY, 'Council',
                'council_offices(offices_index, council_index)',
            ),
      );

      Unit Relations

      array(
           'unitRelation'=> array(self::HAS_MANY, 'Council', 'id'),);

      ViewWithPhonebook Relations

      return array(
           'viewRelation'=> array(self::HAS_MANY, 'Council', 'id'),);

      The code worked if I used the unit relation. The problem I had was with the view, since it did not have a primary key. If I tried to include the relation, I received this SQL error.
      ON
      (`councilRelation`.`id`=`unitRelation`.``) WHERE (year=:year).
      It is clear that the generated SQL was looking for a primary key, but couldn't find it. I searched for a long time for a solution. I finally found the solution at http://codeinch.com/yii-set-primary-key-in-model/. Add a primaryKey method to the model and return the name of the primary key.

      public function primaryKey() {
          return 'ID';
      }

      Once this was set, I could retrieve the Council relation from Council Offices and then retrieve the View relation from the Council.

      $criteria = new CDbCriteria;
      $criteria->condition = 'year=:year';
      $criteria->params = array(':year'=>'2020');

      $data = CouncilOffices::model()
        ->with(array(
          'councilRelation'
             =>array('select'=>'index, year, id'),        
          'councilRelation.unitRelation'
             =>array('select'=>'ID, Name')))
        ->findAll($criteria);

      Sunday, May 3, 2020

      Mojave VM in Catalina

      I just upgraded to Mac OS Catalina and see that my 32-bit applications are no longer supported.

      I have decided to create a Mojave Virtual Machine to be able to run the 32-bit applications.

      Ironically, my VirtualBox application was 32-bit! I downloaded a new, 64-bit version.

      I followed the steps at https://techsviewer.com/install-macos-10-14-mojave-virtualbox-windows/ to create a Mojave ISO image.

      The same site has instructions for creating the virtual machine on Windows, but I want it on Mac. The first few steps can be easily modified for Mojave, 64-bit MacOS. Follow the steps until you are asked to edit the settings after the virtual machine is created. They did not work on Mac. I picked up the steps after the settings were changed and the command line actions were done.

      I found a separate site that just had me start the vm after it is created. I was prompted for the ISO I created. The process continued to the recovery screen for OS. I clicked Install OS. The Mojave image was found and then I was able to follow the normal installation for Mojave.

      Open VirtualBox and click New.


      Proved details for virtual machine (VM), then click Continue.


      Specify memory size of 2G.


      Specify size of hard drive. Suggested 20GB is too small. Trying 100 GB. Click Create.


      Review settings and click Start.


       Select ISO image for mojave and click Start.


      Select language and click arrow.


      Select Disk Utility from the recovery screen.


      Select the VBOX HARDDISK and click Erase in order to format the drive.


      Create a volume name, choose Mac OS Extended and GUID partition. The GUID is needed for a bootable disk. Click Create.


      Drive is created. Click Done.


      Quit Disk Utility from the File menu and select Install macOS from the recovery menu.


      The mojave.iso file will be used automatically to install OS. Click Continue.


      Accept the license by clicking Agree.


      Confirm agreement by clicking Agree.


      Select the hard drive created earlier and click Install.


      Progress is shown.


      After a while, the Apple logo will appear.


      Something went wrong.


      Shut down machine and restarted. Slow progress at the Apple logo. This is the first Apple logo before the recovery menu appears.



      Recreated another VM with same parameters. I made it to recovery menu, erased drive, and started install. Reached the second Apple screen. Freezes with 16 minutes remaining.


      I found a page for getting stuck at 16 minutes: https://forums.virtualbox.org/viewtopic.php?f=22&t=94495. One recommendation is to set CPUs to 2 and not 4. I had it set for 4 the first time and 1 the second time. Setting it to 2 let me get to the 6 minute mark.


      Still waiting... 2 minutes remaining... less than a minute.


      Next came a reboot and sucess!


      Finished setup, but the desktop is too small.


      I installed the VirtualBox extension pack from https://www.virtualbox.org/wiki/Downloads.

      In the preferences for virtual box, I set the display scale to 200%. macOS does not have guest extensions. https://forums.virtualbox.org/viewtopic.php?f=8&t=91128

      Next was to set up a shared folder. Guest extensions are not available for macOS. Instead, share a folder from Sharing in System Preferences. I followed these instructions to share a folder: https://techsupport.screenplay.com/hc/en-us/articles/360035782711-Creating-a-Shared-Folder-between-your-Mac-running-Catalina-and-a-Virtual-Machine


      I created a folder containing my 32-bit apps and shared it.


      The important information is the smb URL. That will be used to connect to shared folder from VM. In the VM, open Finder and select Connect to Server from the Go menu.

      Enter the smb url.


      Select the volumes to mount.


      I have a folder containing the 32-bit software that does not run in Catalina, but runs in the Mojave VM.


      Some of my apps were so old that they could not run on Mojave! I will abandon them instead of installing another, older macOS VM.














      Saturday, January 18, 2020

      Location of resource files in Maven

      I am moving a project from NetBeans into Maven in NetBeans.

      In the original application, I place resource files in the default package (in classes). In the Maven version, these non-compiled classes are not copied to the Target folder, so they cannot be found at run time.

      In Maven, move the files to Other Sources -> src/main/resources.


      Thursday, August 22, 2019

      Using PHP and PerlBrew

      I have phpbrew installed on my mac. I use it to manage my php installation.

      The first command I used was

      phpbrew known

      to view the known PHP versions.

      I had not installed any versions, so

      phpbrew list

      did not show me any.

      So, I checked the version - 1.23. GitHub showed a newer version of 1.26. I decided to reinstall phpbrew.

      https://github.com/phpbrew/phpbrew

      • used curl to install phpbrew.phar
      • moved to my path
      • made it executable
      phpbrew system revealed that my PHP on my Mac under Mojave is outdated, so I installed 7.3 as my system PHP.

      After installing, I updated my PATH with 

      export PATH=/usr/local/php5/bin:$PATH

      I will also add that to my .bashrc

      I was trying to install a different PHP version and received errors about missing bzip2 and some other things. I wound up reinstalling Homebrew, because it could not update itself.

      Homebrew prefix "/usr/local/Cellar/libxml2/2.9.3" does not exist.

      Error: No available formula with the name "bzip2"

      Homebrew formula "bzip2" not found.

      Homebrew prefix "/usr/local/Cellar/oniguruma/5.9.6" does not exist.

      Homebrew prefix "/usr/local/Cellar/mhash/0.9.9.9" does not exist.

      Homebrew prefix "/usr/local/Cellar/curl/7.46.0" does not exist.

      checking for ZLIB support... no

      checking whether to enable bc style precision math functions... yes

      checking for BZip2 support... yes

      checking for BZip2 in default path... not found

      configure: error: Please reinstall the BZip2 distribution

      I tried to install some libraries

      brew install zlib bzip2 libiconv curl

      This is when I tried to update brew and had to reinstall. After brew install, I was able to install the above.

      Next, I intalled

      phpbrew install 7.4.5 +mysql +default

      I still get the error

      Homebrew prefix "/usr/local/Cellar/libxml2/2.9.10_1" does not exist.
      Homebrew prefix "/usr/local/Cellar/oniguruma/6.9.5" does not exist.
      Homebrew prefix "/usr/local/Cellar/mhash/0.9.9.9" does not exist.
      Homebrew prefix "/usr/local/Cellar/openssl@1.1/1.1.1g" does not exist.

      It looks like I need more stuff for Mac OS:

      brew install autoconfig pkg-config

      Then

      brew upgrade

      Could not find autoconfig formula.

      Still can't install PHP. It did find the openssl folder.

      brew install libxml2 onigurma mhash

      Installed missing packages with brew.

      Still can't install PHP versions.

      Inspect

      tail /Users/timdowney/.phpbrew/build/php-7.4.5/build.log

      Missing link to pkg-config, tried

      brew link pkg-config

      Missing libzip

      brew install libzip

      Tried to install 7.4.5 again.

      Congratulations! Now you have PHP with 7.4.5 as php-7.4.5

      * We found that you enabled 'mysql' variant, you might need to setup your
        'pdo_mysql.default_socket' or 'mysqli.default_socket' in your php.ini file.

      * To configure your installed PHP further, you can edit the config file at
          /Users/timdowney/.phpbrew/php/php-7.4.5/etc/php.ini

      To use the newly built PHP, try the line(s) below:

          $ phpbrew use php-7.4.5

      Or you can use switch command to switch your default php to php-7.4.5:

          $ phpbrew switch php-7.4.5












      Friday, July 12, 2019

      Creating Maven from non-Maven project in NetBeans.

      I have a project in NetBeans that is difficult to commit to a version control system (VCS), since the libraries are not saved to the VCS. For several reasons, it is a bad idea to try to save the libraries to the VCS: they are binaries, many duplicates of the files could be saved to the VCS.

      An alternative is to use Maven. The POM file in Maven references all the necessary libraries. When the project is downloaded from the VCS, opened, and run, the POM will guarantee that all necessary libraries are downloaded from the cloud.

      I have created a new Maven project and am copying the files from the original project into the new Maven project. I will list the libraries that are missing as I copy.

      Libraries:

      • org.apache,commons.beanutils - 1.9.3 [jar] local
      • org.apache.log4j - 1.2.15 [jar]
      • org.hibernate.validator.engine - 6.0.10.Final [jar]
      • org.hibernate - 5.2.17
      • org.springframework.beans - 5.0.8 RELEASE [jar] local
      • org.springframework.web - 5.0.8 RELEASE [jar] local
      • org.springframework.context - 5.0.8 RELEASE [jar] local
      • org.springframework.transaction - 5.0.8 RELEASE [jar] local
      • org.springframework.web.servlet - 5.0.8 RELEASE [jar] local 
      • org.springframework.jdbc - 5.0.8 RELEASE [jar] local 
      • org.springframework.orm - 4.2.5 RELEASE [jar] local 
      Missing Libraries:
      • com.paypal.sdk.core .exceptions . profiles .services
      • com.fedex.ws.rate
      • org.apache.fop
      • org.apache.xmlgraphics
      • org.w3c.tidy
      • org.apache.avalon
      In order to make the project portable, I must place the missing libraries into a remote Maven repo.
      • fop.jar
      • avalon-framework-4.2.0.jar
      • jtidy-r938.jar 
      • mailapi.jar
      • paypal_base.jar
      • paypal_juint.jar
      • RateService.jar
      • xmlgraphics-commons-1.4.jar
      For now, I will place these into a folder on the website, until I figure out how to create a Maven repo.

      Harder than I thought. To install into the local .m2/repository, run the maven install command  for each library:

          mvn install:install-file -Dfile=/Users/me/Downloads/jar-missing/jtidy-r938.jar
              -DgroupId=org.w3c.tidy -DartifactId=jtidy -Dversion=r938 -Dpackaging=jar

      I edited the pom file for each library:

             
                  org.w3c.tidy
                  jtidy
                  r938
                  jar
             


      I still needed more dependencies. These are used in log4j 1.2.15, but not in log4j 1.2.16. I upgraded to 1.2.16.

      javax.jms:jms:jar:1.1
      com.sun.jdmk:jmxtools:jar:1.2.1
      com.sun.jmx:jmxri:jar:1.2.1

      Two new dependencies were needed:

              <!-- https://mvnrepository.com/artifact/com.sun.xml/jaxws-rt -->
              <dependency>
                  <groupid>com.sun.xml</groupid>
                  <artifactid>jaxws-rt</artifactid>
                  <version>2.0EA3</version>
              </dependency>
              <dependency>
                  <groupid>javax.jws</groupid>
                  <artifactid>jsr181-api</artifactid>
                  <version>1.0-MR1</version>
              </dependency><br />

      ... and mysql:


              <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
              <dependency>
                  <groupid>mysql</groupid>
                  <artifactid>mysql-connector-java</artifactid>
                  <version>8.0.16</version>
              </dependency>
      
      
      
      I still needed jstl and standard for taglibs.

      I will explore creating a remote repo.





      Friday, May 18, 2018

      Audible on Garmin Nuvi

      I have a Garmin Nuvi 650. It is old. I cannot find the Audible Manager for Mac that allows me to add books to the GPS.

      I used to be able to add books to it.

      I changed the SD card, so the old file structure was gone.

      I downloaded the book files to my computer.

      The fix was simple. Add a folder named Audible in the root of the SD card and copy the book files using Finder. I can listen to the books now.

      Nuvi only recognizes .aa format, not .aax. Before downloading from Audible, select the Format4 option, which will download as .aa files.

      Thursday, May 17, 2018

      Sanitize RV Water System

      I have adapted the notes form https://www.rvtrader.com/research/news-reviews/press-room/rv-how-tips-sanitize-your-rv-water-system.


      1. Drain the water heater.
      2. Open drain plug and all faucets.
      3. Turn off water pump when empty.
      4. The recommended ratio of bleach to water is 1/4 cup per 15 gallons. I have a 24 gallon tank, with a 6 gallon hot water heater. I will add 1/2 cup to 30 gallons.
      5. Add the bleach to a gallon of water and added it to the water tank.
      6. Fill the water tank with potable water.
      7. Run the faucets until bleach is smelled from each.
      8. Close valves.
      9. Drive truck to agitate the mixture.
      10. Let sit for 12 hours.
      11. Drain, including hot water heater.
      12. Fill with water. Run faucets until bleach smell is gone.
      13. Drain and fill.

      Updating Maps on Garmin Nuvi 650

      The internal memory of the Garmin Nuvi 650 is too small for modern maps.

      The Nuvi can handle up to a 32 GB SD card. I have a card of 8 GB with maps from 2014 and 2017.

      I inserted a new card to install the maps for 2019.

      Garmin Express only wants to install to the internal memory.

      Use Garmin Express to install the maps on the computer only.

      On my Mac, the location is in the my Library/Application Support/Garmin. The old maps are installed in the Maps folder. The new maps are installed in the Express/Maps/NA.2019.11/IMG. The folder has two files, .10 and .11. I copied both to the Garmin/Maps folder. Now they appear in MapInstall.

      Use MapInstall to select the memory card on the Nuvi, select the new maps from the drop down and install. The install took 2 hours.

      One year late...

      On Windows, the maps are in /ProgramData/Garmin. (City Navigator North America NT 2020.10.gmap). I did not have to copy the new maps, they were already in the folder that MapInstall reads.

      Monday, May 7, 2018

      Using Maven

      I have added my web development project using Spring to Maven.

      It is easy to set dependencies.

      I had a problem connecting to a database using mysql-connector-java-6.0.6.jar. I received an error about the wrong time zone.

      com.mysql.cj.core.exceptions.InvalidConnectionAttributeException: 
      The server time zone value 'EDT' is unrecognized or represents more than one time zone.
      You must configure either the server or JDBC driver (via the serverTimezone configuration property) 
      to use a more specifc time zone value if you want to utilize time zone support.

      I changed to a different mysql server and received an SSL error.

      com.mysql.cj.core.exceptions.UnableToConnectException: CLIENT_PLUGIN_AUTH is required
      
      I attempted to add useSSL=false to my connection string. but it did not fix the problem.

      I reverted to mysql-connector-java-5.1.44.jar. It fixed both problems.




      Tuesday, April 24, 2018

      Remembering how to use svn

      I have been using git and GitHub for a while, but I still have some repos that are under svn. Of course, I don't remember the svn commands anymore.

      List available repos with
      svn list svn://server:port

      To view all the folders in a particular repo
      svn list svn://server:port | egrep "\$"

      The folder layout should be
      /trunk
      /branch
      /tag

      I do not have any branches, just trunk and tag.

      I work in NetBeans. I checked out the trunk into a local folder, not a NetBeans project. I used the built-in svn client in NetBeans.

      I created a separate NetBeans project, outside the version controlled folder. I created a web app with existing sources.

      To add an existing project to the repo, use the import command on the client. Use a root folder and a trunk subfolder.
      svn import svn://server:port/root-dir/trunk

      I also use the command line for checkout from the project_dir on the server to the local_dir
      svn co svn://server:port/project_dir local_dir






      Tuesday, March 27, 2018

      Where are things in YII

      Constants can be created and accessed in a controller with

      const YEAR = '2018';

      then accessed with

      self::YEAR

      In a Yii app, place constants in config/main.php

      'params'=>array(
      // this is used in contact page
                      'year_senate'=>'2018',
      ),

      then access it with

      Yii::app()->params['year_senate']


      Thursday, March 15, 2018

      MAC Information

      Generating sha256 on Mac

      To generate a sha 256 hash on Mac OSX, use

      openssl sha -sha256 file

      or

      shasum -a 256 file

      Upgrading HTML Tidy to HTML5

      The Html Tidy that shipped with MAC OSX does not support HTML5.

      Get the binary from http://binaries.html-tidy.org/

      Verify the sha256 hash before installing.

      Adding HTML Tidy to TextWrangler

      From http://www.mzoo.org/html-tidy-with-text-wrangler/

      Change to
      ~/Library/Application Support/TextWrangler/Text Filters/

      (I did not have a folder for TextWrangler, so I created one and add a Text Filters subfolder.)

      Create a file named HTML Tidy.sh containing

      #!/bin/sh

      /usr/bin/tidy -utf8 -asxhtml -indent -wrap 100 -quiet 2> /dev/null

      Restart TextWrangler and access filter from Text -> Apply Text Filter -> HTML Tidy

      The last used filter will be available from the Text menu.


      Thursday, February 1, 2018

      Connecting to GitHub in Visual Studio Community for Mac

      I am using build 7.3.3 of Visual Studio Community for Mac.

      I have an existing repo on GitHub that contains a .gitignore for Visual Studio and a Readme file.

      To add a project to the repo, I follow these steps:


      1. Create a new F# console project.
      2. Right-click the top level folder in the project and select Publish in Version Control.
      3. I am asked to enter my credentials. I cancel this operation, since I know it will fail until I perform an update from the repo.
      4. After cancelling the push, I can select update from the version control context menu for the solution.
      5. After entering my credentials, the update completes. (For some reason, I have to enter my credentials multiple times.)
      6. Now I can perform a push that will succeed. All of the files for the project will be added to the repo.
      I am unable to store my username and password credentials in Visual Studio. I have added the credential manager at the command line, and am able to push, fetch, pull without having to re-authenticate. If anyone knows how to remember credentials in Visual Studio for Mac, please let me know.

      Friday, December 29, 2017

      Updating Book for New Edition

      I am using SVN with Netbeans to store the contents of the book.

      To avoid the issue with the project files being added to the repo, I have added the repo source files to a working directory and created a Netbeans project in a different folder, pointing the sources of the project to the working directory files.

      I avoid using the NetBeans SVN and use a separate program. On the Mac I have used svnX, but it has problems with the newer OS. I am trying SmartSVN 9.2. I have a 31 day free, professional trial before reverting to a simple, free version.

      I stored the source for the images in a separate repo. The branch only has the final version of each image.

      The ROOT servlet on the website has an index. Controller that intercepts book and translates to the correct edition of the book.

      I use an Index controller to access the chapters.

      When setting up project on new computer:
      1. checkout repo
      2. create netbeans project from existing sources
      3. allow ssi in web.xml
      4. allow listings in web.xml
      5. edit tomcat-users 
      6. set context as privileged
      One of the projects is a Maven project. After checking out the repo, download dependencies.






      More Blogs

      Followers