Utilizing the tecreations Software Packages



ProjectPath and setProjectDir()

In a nutshell, Java uses a setting called a "classpath". This consists of a path and a directory ie: c:\[java_dir] or /[java_dir], a jar file, a combination thereof, as well as other possible entries, with each entry being a path, ie: path[sep] + 'some_dir' + sep + 'maybe_another' + sep] + ['file.extension'].]. So a classpath contains multiple path entries, some may be relative while others may be absolute. The classpath also supports the '*' wildcard (including all files). Anything referenced on the class path (particularly .class files), are attempted to be loaded, or are otherwise available to an application. Furthermore, one must understand classPathSpec delimiters where classPathSpec is some member of the list of items on a classpath. They should be delimited following this rule (java code):

(File.separator.equals("/")) ? ":" : ";"; // win == ';', mac/linux == ':'

In essence, I strive to keep all my projects in my Documents directory as this makes them relatively easily available from a coding persepective. In this way, they are contained in a central location, facilitating backups, restorations, deployment and processing packages for operation. It does this in a user-friendly way to help the user.

As always, the definitive authority on the topic is the code itself, as it does not lie, however, sometimes comments do. I try to write my code in a certain way, which should be easy to understand and test, helping you to write better code.

ProjectPath.setProjectDir("simple_name") configures ProjectPath for a specific project name. ProjectPath is the source for most path elements. There is also some code in Jar/JarReader related to the /tecreations/jars/ paths (for unpacking dependencies in), but those parts will probably be migrated to ProjectPath over time.



Bootstrapping Building For A Project

With the previous sections in mind, let's look at rolling back to a previous version. The tecreations-core-1.0 package was compiled using DCEVM-11. In order to use this code with a previous version of the JDK, we must recompile as we will get Invalid Class Version errors.

Consider the following examples:

Clean projectDir ca\tecreations of all .class files, compile <defaultpackage>\Build, and run.tecreations-core-1.0

I'm running JDK9 at present, so this package is now in that version. If I wanted to use JDK 8, I'd have to recompile to go backwards in versions. We could also change the code in BuildProject.java to inlude '--release 8' in the list of arguments to javac, but compiling it to the current JDK version also works to make the code translatable. If you are using a JDK >= 11, you probably won't have to recompile. Running older code on newer JDK's seems to always work. Some OS features don't always work.

Also note that the tecreations-core-1.0 package DOES NOT support a --release version. tecreations-0.3.0 and above do.

If you want to build another package, you would use the same commands with a different target. If attempting to build a package that was compiled with a later version of the JDK, you will probably need to Clean as well, which deletes all .class files within a package.

Your best source of information on how this code works is to first read the code and if you still have questions, then email me. My email is at the bottom of this page or on the Contact page.

We only have to remove the .class files if compiling to an older version due to the classloader loading the compiled sources, in this case, resulting in Invalid Class Version errors.

I've tried to make it as easy as possible, however, that's sometimes difficult to achieve.

For version 0.3.0, I did this...

Clean projectDir ca\tecreations of all .class files, compile <defaultpackage>\Build, and run.tecreations-0.3.0

Now in this example, you can see that I used the default package's Build class. We edit and compile .java files (editor + javac [or in our case, Build and SystemCompiler]), and we execute .class'es (java [or in our case, Launcher]).

Also, it recommended that you use the latest version of the tecreations* packages. I am constantly modifying the code tecreations-x.x.x package. It started with tecreations-core-1.0 and has been refactored to 0.2.0 and on.

Currently, I use tecreations-0.3.0.jar to set the ProjectDir("name") to set the ProjectPath in \Documents, and then will maybe use properties\ClassName.properties to store and transfer data. This jar should be considered "in-flux" as it may at times change, as such you may be able to use waybackmachine.org to obtain a previous release. At present, I don't have the functionality to deploy to Maven central, however, I may try to learn to do that. I will then probably use BuildProject to attempt a full build and then probably add the directory to the SystemCompiler, discussed next.




With SystemCompiler, we can select a bunch of projectDir's and compile-on-save. Therefore, when we call code that we have dependended on, the current version typically runs. We do run into problems with Class Version Errors, that just means we have to compile again, typically from change of JDK version.

The SystemCompiler can AutoRunOnStartup (if ran as an Administrator), for Windows. Mac and Linux, you must build your own OnStart functionality. There should be a DebugPrint version and an AutoRemove function that removes it from the startup process.

The SystemCompiler, on Windows, has three output windows -- Paths (displays monitored paths), Output (displays javac compiler output: errors, warnings, etc.), and Status (displays the most recently compiled class Simple Name [ie 'SystemCompiler' when class is equal to 'ca.tecreations.SystemCompiler']).

Output should only display text when there is an error (I forget, maybe on warnings too) output, and Status only shows the next name (it should be: if and only if), the class is compiled, irrespective of warnings, errors and compiler bugs, but that's not real. It prints it out anyway.



Running Applications


For tecreations-0.3.0.jar, running the java -jar tecreations-0.3.0.jar command will work as follows...




As you can see from this image, the user can load classes and dependencies (in the /jars/ directory) for execution, whether in a jar or class path, with or without arguments.

Please refer to the relevant code for precise details on how things work, note there is ca.tecreations.launcher.Launcher and ca.tecreations.SystemTool which contain the bulk of the functionality.

In headless mode, developed to provide remote server compatibility, the target classPath, projectDir, or jarPath must be specified as an argument on the command line and you may optionally -unpack a jar to force unpacking.

For jars, any dependency jars placed in the /jars/* directory structure will be unpacked, if not already, into <user.home>/Documents/tecreations/jars/<jar_simple_name>/jars/

To force re-unpacking, for example after changing dependencies, simply delete the appropriate /jars/ directory in the tecreations directory. Note that the tecreations directory is a special path I use internally for a variety of purposes, mostly properties, holding jars for jar dependencies and some static data files. Likewise, with .properties files, you may delete any of them and the appropriate class will re-generate the defaults.


For testing multiple operating system commands, I'll often use the CommandLauncher. It lets me execute an operating system command, optionally save the command to the properties between executions and replay them.


For launching classes with a set of dependency jars, as we've discussed, there is the Launcher. For instances where the Launcher is ineffective, there is also Relauncher.

Relauncher will 're-launch' a class, with the classpath constructed of <target><delimiter><delimited_jars_in_projectDir_jars_subpath>.

As always, check the code, but if I remember correctly: java -cp tecreations-0.3.0.jar ca.tecreations.launcher.RelaunchJar <target> [args].

Relauncher determines the target type (projectDir, classpath, or .jar) and launches either RelaunchJar or RelaunchProject, as appropriate.

The dependencies and refreshing them are an ongoing issue. We are trying to work it out, but it is, at present, an unsuitable solution.





I've been using a modified pom.xml system utilizing Eclipse Aether and Maven Resolver via Java code (programmatically). The result is DependencyViewer.

This class houses a JTree for displaying the transitive dependencies for an application, as resolved by Maven Resolver using a custom tec.xml file. Its' format is similiar to a Maven pom.xml file, except that it only retrieves the transitive dependencies for the artifacts entered in the <dependencies> section.

This should allow you to use a pom.xml file as a source for the dependencies, and upon saving the text, the application will resolve and download the dependency .jars. It used to use the <dependenciesManagement> section and list those also, but it appears that I have removed that functionality. (Probably due to too many failures.)

Currently, it downloads and creates a repository in C:\temp\, but that can, of course, be altered. That's one of the benefits of using this code, complete freedom.

After completing the resolving and downloading, the application ouputs "Action done." You may then commit the dependencies to a /jars/ directory, with or without emptying it first. I usually need to empty, but sometimes, if I'm just adding a dependency, I'll simply commit the new set to the /jars/ directory.

The application will output "Action done." after copying the committed jars.

It should be noted that for Spring projects, I'm able to easily add the dependencies and it works. There have been instances where it wouldn't and in every case I found it was something I was doing wrong that caused the failure. Looking at my projects, I have the removal options and the exclusions due to code 'over-shadowing', where multiple versions compete for dominance....?

In case you haven't understood how the /jars/ directory works with the tecreations* packages, /jars/ is a special directory. Any .jar files placed in this directory will be entered on the class path argument when Launch'ing or Relaunch'ing. CommandLauncher only works with shell commands, so it doesn't construct a classpath, you must do it manually for that. Nevertheless, in Launcher and Relauncher, we construct the -cp argument, using the source classPath/jarPath and the contents of the jars directory (relevant to the target, jars use tecreations/jars/simplename/jars/). Note that you may also break up your /jars/ directory into /jars/path1 /jars/path2, etc. The manner in which the class path argument is formed is using /path/*<java:File.separator> elements, therefore, the classpath is kept as short as possible to facilitate debugging.

Specify a valid POM file and include your dependencies in the section, save POM text or reload, and commit to target. tecreations will use it.





For this, you require the client, server and for all of their PKI keys and certs to be in the correct locations. You may use the SecurityTool and it's docs to create a compatible configuration. You could write your own, use Spring Security, or use mine. Please don't create your own PKI, let the WORLD do that. This is a Bouncy Castle implementation. I recommend learning reviewing the code within the SecurityTool jar, particularly the Keystore class which contains references to the original source reference material (if available).

The client and server utilize a simple command passing/processing system. they open a connection, handshake, communicate and close connection when done.

The code for each may be found in the /net/ directory within the downloads, inside NetworkFS.jar, which is just a repository of the code -- this jar is not executable.

Functionality is broken into discrete, testable chunks of code.

At present, with the tecreations-0.3.0.jar platform classes, you can get the directory listing, file sizes, oldest/newest files, and transfer files of any type or size to or from the remote host.

Of course, if you are using the tecreations-0.3.0.jar as a dependency, you can use any code contained within, therefore to implement a class which executes an operating system command, with or without output, blocking or non-blocking, is trivial.

The capacity to compile upon delivery, test, and anything you can code exists to be potentially functional. All of this functionality may be accessed programmatically.


Security Applications

There are a few security related applications. FileEncrypter and FileDecrypter work to encrypt/decrypt a file using AES256-GCM algorithm at unlimited strength.

There is also FileAccessMonitor and SecurityWatcher to monitor file access.

There is PortScanner to determine open ports for security or development purposes.

Finally, there is SecurityTool to manage PKI aspects. Note however, this tool is in it's own jar, tecreations-security-1.0-BC1.69, which depends on Bouncy Castle 1.69. You may access this tool using its' own jar, since it has a bundled tecreations Launcher, although much older code.