how to show the actual modulepath? - junit4

For debugging I have a need to see the actual modulepath. How can I print it out at runtime?
The problem: Using ServiceLoader to load a module against a defined API works fine in normal runtime environment but not in testing. I'd got to find out why.
As I am new to ServiceLoader, it may not to be enough that a provider module can be found on modulepath. However, my first question is: is it on modulepath even in test environment?

When you want to check the presence of a module, you can straight-forwardly check the presence of a module, e.g.
String moduleName = "java.compiler";
ModuleLayer.boot().findModule(moduleName)
.ifPresentOrElse(
m -> System.out.println(m + " loaded via " + m.getClassLoader()),
() -> System.out.println(moduleName + " not found"));
When the module is not present, you can check module path using the non-standard system property,
System.out.println(System.getProperty("jdk.module.path"));
Besides possibility of a mismatching path, it’s worth checking the context loader of each envi­ron­ment if loading a service fails in one environment, as the method ServiceLoader.load(Class) uses the context loader for searching.
Also check that the module’s classes are not accidentally provided on the old class path.

Related

Can I use environment variables or tilde in module.modulemap?

My module.modulemap file looks like this:
module CompanyInternalSDK {
header "~/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
export *
}
However, I get this error:
/Users/username/Path/To/Project/CompanyInternalSDK/module.modulemap:2:12: error: header '~/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h' not found
header "~/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
^
It compiles just fine when I use the absolute path without the tilde, but since this will be distributed like this to all developers, I want to use the tilde. Is there any way to make this work correctly?
I also tried to use an environment variable in the header string, but that didn't work either:
module CompanyInternalSDK {
header "${HOME}/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
export *
}
/Users/username/Path/To/Project/CompanyInternalSDK/module.modulemap:2:12: error: header '${HOME}/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h' not found
header "${HOME}/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
^
No, the modulemap syntax does not expand tildes or environment variables. It ultimately just expects to stat the path you gave it, and if no file's there, it'll gripe.
Here's where the header file lookup is kicked off, during lexing of the module map file.
It ultimately passes the path to the SourceManager's FileManager to produce a File object, as here for a header in a framework's Headers/ public header folder.
getFile ultimately ends up calling out to getStatValue, which does a cache lookup.
The FileSystemStatCache::get eventually grounds out in LLVM's filesystem abstraction, where it calls sys::fs::status, which is documented to act like POSIX stat.
POSIX stat works with paths as-is, no tilde or environment variable expansion - the common availability of those is due to the shell helping you out, not something that happens automatically most of the time at the system level.
However, it's standard to use relative paths in module maps. The lexer respects this, and all the module map docs demonstrate this. In the common case where your module map file is colocated with your library and installed alongside it, this should suffice to properly resolve the paths.

Where do I put my resources in Scala?

While studying using Scala with JavaFX I have met the following code in a ProScalaFX example:
val resource = getClass.getResource("AdoptionForm.fxml")
if (resource == null) {
throw new IOException("Cannot load resource: AdoptionForm.fxml")
}
...
val root: jfxs.Parent = jfxf.FXMLLoader.load(resource)
Where do I put the actual "AdoptionForm.fxml" content in this case? Unfortunately I am neither familiar with using resources in Java.
I use SBT as the building system and Idea as an IDE.
There is a related question which suggests a way (putting the resource files in "src/main/resources" or "src/main/resources/packagename"), but it also says it doesn't work actually (needless to say I have tried).
src/main/resources is the correct location for placing resources in a default SBT configuration.
However, one has to be aware of the difference between getClass.getResource and ClassLoader.getResource. Using getClass.getResource("AdoptionForm.fxml") requires the file to be located in a path which corresponds to the package of the class.
For instance: If the class is located in com.domain.utils then the resource must be located at src/main/resources/com/domain/utils/AdoptionForm.fxml.
In order to switch from package-relative locations to absolute locations one can either use ClassLoader.getResource or just prepend the resource string with a /.
Example: getClass.getResource("/AdoptionForm.fxml") loads the resource from src/main/resources/AdoptionForm.fxml

Accessing the path to the test case in Selenium IDE

Is it possible to evaluate the path to the current test case in Selenium IDE? File uploads require a full path, and hard coding one breaks portability.
A good workaround would be to add a test file to the project's resources directory. Every member of the team would have access to the file.
WebElement fileInput = driver.findElement(By.locator("yourButton"));
String filePath = YourClass.class.getResource("/" + fileName).getPath();
fileInput.sendKeys(filePath);
I have found that putting the above code block in a helper method that can be accessed by all test classes works best.

How can I make the Entity Framework Type Provider use the runtime config file?

I have an F# library project that I'm using from a C# web project. I would like to use the Entity Framework Type Provider in my F# project, and have it get the connection string from the Web.config - but I'm having trouble getting this working.
type internal FooDb =
SqlEntityConnection<ConnectionStringName="FooDb", Pluralize=true>
At design time, I'm required to have an App.config file in the F# library project with a connection string having the matching name.
At runtime, when calling my F# code from the C# web project, I get an error that it can't locate the "App.config" file. This surprises me, because I was expecting that at runtime it would just use ConfigurationManager.ConnectionStrings to load the connection string from the currently-active config file (in the case of a web app, Web.config). However this doesn't seem to be the case.
I tried adding the ConfigFile parameter:
type internal FooDb =
SqlEntityConnection<ConnectionStringName="FooDb", ConfigFile="Web.config", Pluralize=true>
But this just made it complain at design time that it couldn't find Web.config.
Then I renamed the App.config file in the F# library project to Web.config and that seems to have gotten things working. However, I'm uneasy about this solution. Is this really how it's intended to work? I have to have a web.config file in my library project? What would I do if I wanted to use the same library from a command-line executable, and in that environment the config file is called AssemblyName.exe.config?
Forcing me to hard-code the name of a config file that can have different names in different contexts seems very brittle, and a poor design. Please tell me I'm missing something.
The issue you've encountered seems rather unfortunate indeed, and I don't know whether you are missing something or not. However, the SqlEntityConnection documentation says that FooDb should have a GetDataContext overload where a "connectionString parameter may be used when the connection string is determined at runtime." Perhaps that will give you a decent enough work around (i.e. pass in the connection string from ConfigurationManager.ConnectionStrings yourself).

GWT: Get constants in server side

I'm trying to get the constants (ConstantsWithLookup) stored in the client side in my server side, but it can't figure out how to do it. I have my constants interface and my constants properties in the same folder.
I've tried tips of other similar threads with no success.
I tried Hermes, gwt-i18n-server, gwt-dmesg, GTWI18N, using a ResourceBundle, trying to get source file properties.
For the first two, it seems that the main reason is the outdated support for the newest GWT version. As for the ResourceBundle, it cannot find the properties file because at deployment, there isn't a properties file, just a Constants.class.
I'm trying to avoid changing my properties file to another location (like /WEB-INF/constants).
I'm using Hermes with GWT 2.5.0.rc1, and it works fine. Usage:
put hermes-1.2.0.jar into war/WEB-INF/lib
Then on the server side write something like
MyConstantsWithLookup my = Hermes.get(MyConstantsWithLookup.class, "de");
String string = my.getString(key);
A properties file MyConstantsWithLookup.properties must exist in the same package as MyConstantsWithLookup.java, even if that properties file is empty (which might be the case if you're using #DefaultStringValue etc.)
Also add MyConstantsWithLookup_de.properties etc.
Make sure, that these properties files are copied next to your classes when compiling. Javac doesn't do that, so it must be done in an additional build step (Eclipse usually does this automatically, but it won't happen by itself when you build e.g. with Ant)
Many build setups will skip the java and properties files from the "client" package when compiling the server side. In that case, put your constants files in the "shared" package (if you have one).