Load Assembly stored in Package (C#) - assemblies

Is it possible to load an assembly that is stored in a package (a System.IO.Packaging type package, that is) in C#?
I am using ReflectionLoadFrom and passing the Uri that is formed by the PackageUriHelper, which looks correct. At runtime, I get a FileLoadException.
Edit:
Here's the code loading the assembly:
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(mainDllUri.ToString());
Here's the code that forms the URI:
UriBuilder packageUriBuilder = new UriBuilder();
packageUriBuilder.Path = this.path;
packageUriBuilder.Scheme = "pack";
Uri packageUri = packageUriBuilder.Uri;
Uri partUri = currRelationship.TargetUri;
return PackUriHelper.Create(packageUri, partUri);
I know you can use other URIs (e.g. file://), but I've never seen anyone use the pack URI.

Related

Unable to load assemby built with F# compiler services via 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.

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

Execute external jar file from pentaho

I am trying to execute a custom jar file from the modified javascript value. My Jar name is JsonParsing.jar which I have placed in lib folder. When I am trying to execute a method in the jar its giving me the error:
ReferenceError: "JsonParsing" is not defined.
Code Snippet:
var package1 = JsonParsing.parseJson.ParseJSON;
xyz=package1.processJson(data);
The Javascript kettle uses is Rhino. Rhino gives Javascript access to Java classes, but it's not completely transparent.
Check out the Rhino docs on Scripting Java.
I have resolved the issue. I was missing the Packages thing while creating the instance. As I had a static method in my class I have to call it in the following way. (parseJson is my package name and ParseJSON is my class name) . Here Packages is the default class provided by Rhino
var call = Packages.parseJson.ParseJSON;
xyz=call.processJson(data);
If it is a non static method I had to create an object in the following way
var call = new Pakages.parseJson.ParseJSON();
xyz=call.processJson(data);

Use AppDomain.Load(byte[]) without loading from file?

I crack my mind... I trying to manually load and unload domain with one assembly:
var domainInfo = new AppDomainSetup
{
PrivateBinPath = baseDir
};
_hostedDomain = AppDomain.CreateDomain("Domain", null, domainInfo);
_hostedDomain.UnhandledException += HostedDomainUnhandledException;
_hostedDomain.DomainUnload += _hostedDomain_DomainUnload;
var bytes = File.ReadAllBytes("Facade.dll"); // Loads facade from hosts location.
_hostedDomain.Load(bytes);
string asmName = Path.Combine(baseDir, Properties.Settings.Default.AssemblyName);
bytes = File.ReadAllBytes(asmName);
var entryPoint = _hostedDomain.Load(bytes); // exception here!
And what I see:
When I tryed to load assembly I see that system load it from CurrentDir/assemblyname.dll (and fails).
Exception: System.IO.FileNotFoundException:
Could not load file or assembly Worker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:#Development!test\trunk\bin\Debug\Bootstrapper.vshost.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///D:/#Development/!test/trunk/bin/Debug/Worker.DLL.
LOG: Attempting download of new URL file:///D:/#Development/!test/trunk/bin/Debug/Worker/Worker.DLL.
LOG: Attempting download of new URL file:///D:/#Development/!test/trunk/bin/Debug/Worker.EXE.
LOG: Attempting download of new URL file:///D:/#Development/!test/trunk/bin/Debug/Worker/Worker.EXE.
BTW. It is impossible to use LoadFrom due to limitations (I've got the problem with XML serialization....).
Wat the hell .NET doing in this routines?
Why it is so hard to load and unload domain?
Thanks for the help!

Resources