Unable to load assemby built with F# compiler services via reflection - reflection

I keep getting the following error message when I tried to load (via reflection) a .dll built using F# compiler services (even though the Equals method being complained about does exist in the build):
Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Method 'Equals' in type 'XXX' from assembly 'YYY', Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
I'm using .NET Core on Ubuntu.
However, if I build using Visual Studio Code, I'm able to load the assembly. I opened both builds and I noticed the version that doesn't work has an override for one of the Equals method while the version that does, doesn't. I'm not sure if this is of consequence:
[CompilerGenerated]
public sealed bool Equals(object obj, IEqualityComparer comp)
vs
[CompilerGenerated]
public sealed override bool Equals(object obj, IEqualityComparer comp)
Additionally, when I check the references using dnSpy, the version that works has a reference to .netstandard while the version that does not does not have this reference. I've tried adding a reference to the .netstandard .dll as part of the compilation but this doesn't seem to have any effect.
The code I'm trying to build is a simple record, roughly equivalent to the following:
namespace Xxx
open System
type Yyy =
{
ServiceCategory : string
DateRange : DateTime
}
Here's the code I used to build using F# Compiler Services:
// Detect the file location for the library that defines the object type
let corelibRefLocation = typeof<Object>.GetTypeInfo().Assembly.Location
let corelibRefDirectory = Path.GetDirectoryName(corelibRefLocation)
let mscorlibRefLocation = sprintf #"%s/mscorlib.dll" corelibRefDirectory
let systemRuntimeRefLocation = sprintf #"%s/System.Runtime.dll" corelibRefDirectory
let netStandardRefLocation = sprintf #"%s/netstandard.dll" corelibRefDirectory
let staticArgs =
[|
"fsc.exe"
"--noframework"
"-o"; outputPath;
"-a"; sourcePath
|]
let references =
[|
"-r"; corelibRefLocation
"-r"; systemRuntimeRefLocation
"-r"; mscorlibRefLocation
"-r"; netStandardRefLocation
|]
let args = Array.concat([|staticArgs; references|])
let errors, exitCode =
checker.Compile(args)
|> Async.RunSynchronously
match (errors, exitCode) with
| [||], 0 -> Console.WriteLine("OK!")
| _ -> Console.WriteLine("Not OK!")
I'm not sure why the .dll isn't loading and what I need to do differently.
UPDATE:
I've upgraded from .net Core 2.1. to .NET Core 3.0 and even though the generated code now no longer includes the override, the issue persists. The only significant difference between the version that works (compiled with VSCode) and the version that doesn't (compiled with FCS) that I can observe now is that the FCS version has an explicit reference to mscorlib and System.Private.CoreLib. However, I'm unable to get the code to compile without these explicit references.

Related

"TS2729 [ERROR]: Property 'boundary' used before its initialization" in extern library

After updating my deno version to 1.9 today I had started having the following problem when running my tests or my scripts:
TS2729 [ERROR]: Property 'boundary' is used before its initialization.
readonly dashBoundary = encoder.encode(`--${this.boundary}`);
~~~~~~~~
at https://deno.land/std#0.63.0/mime/multipart.ts:266:52
'boundary' is declared here.
constructor(reader: Deno.Reader, private boundary: string) {
~~~~~~~~~~~~~~~~~~~~~~~~
at https://deno.land/std#0.63.0/mime/multipart.ts:269:36
I checked and I am not using the mime repository anywhere in my code, instead some other repositories must use it.
I am using the following repositories:
x/abc
std/uuid
std/fs
std/path
std/fmt
std/testing
I made sure that I am explicitely using the newest version for all of the imports of the std library (std version 0.93.0).
When I am running the files that are importing the std library (instead of running the entire application) no errors occur.
Does anyone have an idea how to resolve the error?
It seems like the repository x/abc was the problem.
I did not add a version when importing it implicitly. When importing implicitly it in the following way it worked:
import abc from "https://deno.land/x/abc#v1.3.1/mod.ts";

InvalidOperationException: Could not find 'UserSecretsIdAttribute' on assembly

After deploying ASP.NET Core app to azure and opening the site, I get the following error:
InvalidOperationException: Could not find 'UserSecretsIdAttribute' on
assembly '******, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.
The exception details also include that the error happens at Startup.cs on this line of code:
builder.AddUserSecrets();
Thank you
There was an update to the user secrets module just recently. Version 1.0.1 and up now requires you specify an assembly-level attribute for the id of the user secrets, or as a fallback, the way it was previously in project.json.
Here is the announcement on GitHub: https://github.com/aspnet/Announcements/issues/209
You can define the secrets id in the .csproj like this:
<PropertyGroup>
<UserSecretsId>aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed</UserSecretsId>
</PropertyGroup>
This generates the following assembly-level attribute. Alternatively, instead of adding it in the .csproj file, you can of course add it yourself e.g. to Startup.cs:
[assembly: UserSecretsId("aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed")]
Also, you should use:
builder.AddUserSecrets<Startup>();
It will search for that attribute in the assembly of the given type, in this case I used the Startup class.
Note: this will be deprecated in 2.0: (1.0.2 and 1.1.1 have marked it obsolete)
builder.AddUserSecrets();
I checked the source code for the user secrets configuration, and calling AddUserSecrets() without the type does this:
var attribute = entryAssembly.GetCustomAttribute<UserSecretsIdAttribute>();
if (attribute != null)
{
return AddUserSecrets(configuration, attribute.UserSecretsId);
}
// try fallback to project.json for legacy support
try
{
var fileProvider = configuration.GetFileProvider();
return AddSecretsFile(configuration, PathHelper.GetSecretsPath(fileProvider));
}
catch
{ }
// Show the error about missing UserSecretIdAttribute instead an error about missing
// project.json as PJ is going away.
throw MissingAttributeException(entryAssembly);
It's trying to find the UserSecretsId attribute on your assembly, and failing that, checking if it could find it in project.json. Then (as commented) returns an error about the missing attribute as they wouldn't want to complain about project.json anymore as it is being deprecated.
I want to add to this answer, for those in my situation.
I am writing a .NET Core console app, trying to use the secrets manager (not sure it's meant for console apps). The only way I was able to rid myself of the error was using the assembly level attribute on the assembly where I was using the secrets manager.
As I said, I am not sure if the secrets manager is meant for console apps. So maybe there is an issue with .xproj files vs. .csproj files.
My .NET Core 3.1 Worker Service required additional setup (more than a Web project).
In Program.cs in the CreateHostBuilder method I needed this:
.ConfigureAppConfiguration((ctx, builder) =>
{
// enable secrets in development
if (ctx.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Worker>();
}
})
But (unlike my Web project) I explicitly needed to add this nuget package:
install-package Microsoft.Extensions.Configuration.UserSecrets
After that I could access secrets.

XSLT document() relative path resolving to IIS.exe

I have a .NET WebApi project with two files, both of which have been marked as embedded resources and are deployed with the application. The files are also both in the same directory in the deployed application:
./xsl/transform.xslt
./xsl/schema.xsd
The xslt file needs to load the xsd file via the document() function:
<xsl:template match="*[not(local-name() = document('schema.xsd')//xs:element/#name)]" />
<xsl:template match="#*[not(local-name() = document('schema.xsd')//xs:attribute/#name)]" />
Unfortunately, I'm getting an exception at runtime that indicates that the relative path being resolved is the program files directory for IIS and not the directory where transform.xslt is located:
{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred while loading document 'schema.xsd'. See InnerException for a complete description of the error.",
"ExceptionType": "System.Xml.Xsl.XslTransformException",
"StackTrace": "<ommitted>"
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Could not find file 'C:\\Program Files (x86)\\IIS Express\\schema.xsd'.",
"ExceptionType": "System.IO.FileNotFoundException",
"StackTrace": "<omitted>"
}
}
I don't want to use an absolute path here because I don't want to become overly dependent on the environment the application is deployed into. Is there anyway to force the relative path source from the same directory that transform.xslt is deployed into at runtime?
For reference, the absolute path to the xslt file at runtime was:
C:\\MyFolder\\MyCode\\MyProject\\Web\\bin\\xsl\\transform.xslt
EDIT:
As requested, the following is (roughly) the code that is used to load the xslt from the manifest resource stream and run the transform. This code is unwrapped from several different custom packages to boil it down into core libraries, so don't worry about the stream management. I promise the real code is much safer:
XmlReader input = this.GetInput();
Stream ouput = new MemoryStream(4096);
Stream stream = typeof(ClassUsingTransform).Assembly.GetManifestResourceStream("transform.xslt");
MemoryStream mStream = new MemoryStream(stream.ToByteArray());
var navigator = new XPathDocument(mStream).CreateNavigator();
XslCompiledTransform processor = new XslCompiledTransform();
processor.Load(navigator, XsltSettings.TrustedXslt, new XmlUrlResolver());
processor.Transform(input, new XsltArgumentList(), output);
The XmlUrlResolver could not be unwrapped into builtins easily, but the type used inherited from XmlUrlResolver and didn't appear to modify any of the builtin settings. Most of the work done in the derived classes seemed to focus on performance optimizations. If anyone thinks the implementation here is important, I can try to unwrap that class a bit better.
The XsltArgumentList used was also a derived type, but the argument list is empty as far as I can tell.

Jasper Reports "package net.sf.jasperreports.engine does not exist" exception in JDeveloper 11.1 using WebLogic only in EAR Web Page

I'm using JDeveloper 11.1, Oracle 11 and TIBCO JasperReports 6.0.1.
I'm having problems trying to generate Jasper Reports from my web page (ViewController) while using an ApplicationModule (Model - EJB) for doing that. At the end the PDF file has to be sent via email, that's why I let it into the Model project.
If I execute the ApplicationModule, it works fine, no exceptions, the PDF is very well generated and sent.
However, if I execute the client method since a web page I got this exception :
net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:4: package net.sf.jasperreports.engine does not exist
import net.sf.jasperreports.engine.*;
^
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:5: package net.sf.jasperreports.engine.fill does not exist
import net.sf.jasperreports.engine.fill.*;
^
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:18: cannot find symbol
symbol: class JREvaluator
public class Simple_Blue_1429546047623_56582 extends JREvaluator
^
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:25: cannot find symbol
symbol : class JRFillParameter
location: class Simple_Blue_1429546047623_56582
private JRFillParameter parameter_REPORT_LOCALE = null;
^
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:26: cannot find symbol
symbol : class JRFillParameter
location: class Simple_Blue_1429546047623_56582
private JRFillParameter parameter_Description = null;
^
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:27: cannot find symbol
symbol : class JRFillParameter
location: class Simple_Blue_1429546047623_56582
private JRFillParameter parameter_JASPER_REPORT = null;
^
C:\Users\rodmar\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\Simple_Blue_1429546047623_56582.java:28: cannot find symbol
symbol : class JRFillParameter
location: class Simple_Blue_1429546047623_56582
private JRFillParameter parameter_REPORT_VIRTUALIZER = null;
^
I'm just pasting a fragment.
I'm using other .jars as POI, for reading .xlsx files and inserting then into database so I don't know why I can access POI without any problem but at the same time I don't have Jasper Reports available.
I have already searched some solutions in the web but nothing solves my problems. I get some information about jdt-compiler but I don't find it into JasperReports suite. My project is really a mess with all these libraries, maybe I'm missing or adding too many ?
My EAR project at the moment is like this :
The EAR\lib:
This is a kind of a problem for jars settings, or something like that. I had already found this page but it is really strange, I don't think that my issue is something so complicated.
http://docs.oracle.com/cd/E25178_01/fusionapps.1111/e15524/adv_wls_e.htm
EDIT 1 :
I tried to look to my classpath using this code :
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for (URL url: urls) {
logger.info(String.format("Classpath: %s.", url.toString()));
}
And I get this output. POI is not here but why, I'm using it without any problems while I'm not been capable of using JasperReports ?
1 ) Is POI.jar by default used in WebLogic 10.3 basic installation ? NO
EDIT 2 :
I've discovered that in WebLogic is necessary to access weblogic.utils.classloaders.GenericClassLoader which sends me all the libraries that belong to this EAR application. Using it, Jasper Reports are available however I don't know what to do to access them successfully...
GenericClassLoader jre = (GenericClassLoader) JREvaluator.class.getClassLoader();
logger.info(String.format("jre: %s, s.", jre, jre.getClassPath()));
Thanks you very much,
Well, as somebody says it was necessary to use jdt-compiler-3.1.1.jar. I added it to /lib folder and now it is working.
It's really strange that this .jar is not in the installation product for TIBCO Jasper Reports 6.0.0 actually I descend until JR 3.7.6 which is the lowest version. The file is from 28/12/2008...
Nice...
I used eclipse ecj-4.3.1.jar and it works.
First checks the dependencies of jasperReports - for example version 6.1.0 - https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports/6.1.0
With this you can see if there is any dependency that is missing in your lib directory (webApp) or inside your .jar (if it is a main application of java).
That mistake also happened to me, and I solved it by adding dependence
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.3.1</version>
I hope it supports you

Asp.net release build vs debug build

How do I determine if my app was compiled as "release" instead of "debug"? I went to VS 2008 Project Properties > Build and set the configuration from Debug to Release but I noticed no change? This is an ASP.NET project.
HttpContext.IsDebuggingEnabled
If you want to know if the dll was built in Debug mode, with the debug attributes, then your best bet is reflection.
Taken from "How to tell if an existing assembly is debug or release":
Assembly assembly = Assembly.GetAssembly(GetType());
bool debug = false;
foreach (var attribute in assembly.GetCustomAttributes(false)){
if (attribute.GetType() == typeof(System.Diagnostics.DebuggableAttribute)){
if (((System.Diagnostics.DebuggableAttribute)attribute)
.IsJITTrackingEnabled){
debug = true;
break;
}
}
}
This will get the assembly that is calling that code (in effect itself), and then set the debug boolean to true if the assembly was compiled in debug mode, otherwise it's false.
This could easily be dropped into a console app (as in the linked example), and then you pass in the path of the dll/exe you want to check. You would load the assembly from a path like this:
Assembly assembly =
Assembly.LoadFile(System.IO.Path.GetFullPath(m_DllPath.Text));
For one in Web.config debug will be set to true, however you can actually set this in a release application too.
In debug however defines like DEBUG are set, so it's simple to do:
bool is_debug;
#ifdef DEBUG
is_debug = true;
#else
is_debug = false;
#endif
You need to look for more than IsJITTrackingEnabled - which is completely independent of whether or not the code is compiled for optimization and JIT Optimization.
Also, the DebuggableAttribute is present if you compile in Release mode and choose DebugOutput to anything other than "none".
Please refer to my posts:
How to Tell if an Assembly is Debug or Release and
How to identify if the DLL is Debug or Release build (in .NET)

Resources