Log4Net doesn't log custom exception correct - log4net

I'm using log4net and logging exceptions. but i want to log current object on exception time but i couldn't.
I created exception and add object to exception's data property then log exception by log4net. log4net's exceptions message doesn't contain my object.
my code such as;
try
{
Exception exp = new Exception("critical error");
exp.Data.Add("Eror Object", viewModel);
throw exp;
}
catch (Exception exp)
{
_logManager.Error(exp);
}
my viewModel object;
[Serializable]
public class CartTransferViewModel
{
public CartTransferViewModel()
{
Model = new ModelObject();
}
public ModelObject Model { get; set; }
public string InformatinMessage { get; set; }
public bool? IsActive { get; set; }
}
And my Model object serializable too. but log4Net's exception message like this;
System.Exception: critical error
at FooProject.FooClass.FooMethod() in d:\FooProject\FooClass.cs:line 200
I'm remove serializable attribute then re run my application, error code did change to;
System.ArgumentException: Argument passed in is not serializable.
Parameter name: value
at System.Collections.ListDictionaryInternal.Add(Object key, Object value)
at FooProject.FooClass.FooMethod() in d:\FooProject\FooClass.cs:line 200
How to log my custom exception with my objects?

Ok ,if i got your question. i do the something similar . i use logger to write the exception . But i use Exception.Data property.
here is the example , example contains
1) Info class , which needs to be written
2) Sample class with method , write infoclass when exception happens
3) Utility class which formats the exception
[Serializable]
public class FlatFileItem
{
ArrayList errorlist = new ArrayList();
public FlatFileItem()
{
if (errorlist == null) { errorlist = new ArrayList(); }
}
//Name of the file
public string FileName { get; set; }
public override string ToString()
{
return string.Format(#"FlatFileItem (Unzip FTPLineItem) => FileName:{0}", this.FileName);
}
}
public class someclass {
public void somemethod(){
try{
// throw exception here
} catch (Exception ex)
{
ex.Data["flatfile"] = Convert.ToString(flatfile); //Using data property
flatfile.HasErrors = true; //not there in above example
flatfile.Parent.AddErrorInfo(ex); //not there in above example
logger.Error(String.Format(ex.Message)); //not there in above example
throw ( new Exception ("yourmsg",ex)); //if you want to do this
}
}
}
//Now i use this utility method to write out everything at very top level exception
public class ExceptionInfoUtil
{
public static string GetAllExceptionInfo(Exception ex)
{
StringBuilder sbexception = new StringBuilder();
int i = 1;
sbexception.Append(GetExceptionInfo(ex, i));
while (ex.InnerException != null)
{
i++;
ex = ex.InnerException;
sbexception.Append(GetExceptionInfo(ex, i));
}
return sbexception.ToString();
}
private static string GetExceptionInfo(Exception ex, int count)
{
StringBuilder sbexception = new StringBuilder();
sbexception.AppendLine(string.Format(""));
sbexception.AppendLine(string.Format(""));
sbexception.AppendLine(string.Format("************************************************"));
sbexception.AppendLine(string.Format("************************************************"));
sbexception.AppendLine(string.Format(" Inner Exception : No.{0} ", count));
sbexception.AppendLine(string.Format("************************************************"));
sbexception.AppendLine(string.Format("=================================================="));
sbexception.AppendLine(string.Format(" Error Message : {0} ", ex.Message));
sbexception.AppendLine(string.Format("=================================================="));
#region Mine Thru data dictionary
try
{
sbexception.AppendLine(string.Format("=================================================="));
sbexception.AppendLine(string.Format(" Data parameters Count at Source :{0}", ex.Data.Count));
sbexception.AppendLine(string.Format("=================================================="));
string skey = string.Empty;
foreach (object key in ex.Data.Keys)
{
try
{
if (key != null)
{
skey = Convert.ToString(key);
sbexception.AppendLine(string.Format(" Key :{0} , Value:{1}", skey, Convert.ToString(ex.Data[key])));
}
else
{
sbexception.AppendLine(string.Format(" Key is null"));
}
}
catch (Exception e1)
{
sbexception.AppendLine(string.Format("** Exception occurred when writting log *** [{0}] ", e1.Message));
}
}
}
catch (Exception ex1)
{
sbexception.AppendLine(string.Format("** Exception occurred when writting log *** [{0}] ", ex1.Message));
}
#endregion
sbexception.AppendLine(string.Format("=================================================="));
sbexception.AppendLine(string.Format(" Source : {0} ", ex.Source));
sbexception.AppendLine(string.Format("=================================================="));
sbexception.AppendLine(string.Format(" StackTrace : {0} ", ex.StackTrace));
sbexception.AppendLine(string.Format("=================================================="));
sbexception.AppendLine(string.Format(" TargetSite : {0} ", ex.TargetSite));
sbexception.AppendLine(string.Format("************************************************"));
sbexception.AppendLine(string.Format(" Finished Writting Exception info :{0} ", count));
sbexception.AppendLine(string.Format("************************************************"));
sbexception.AppendLine(string.Format("************************************************"));
sbexception.AppendLine(string.Format(""));
sbexception.AppendLine(string.Format(""));
return sbexception.ToString();
}
}

Related

Getting NullpointerException while executing with singleThreadExecutor and executorServices

I created a program using threads to read data from file and dispay. Am getting Null pointer exception, first time thread 1 is printing the firstrecord from textfile and second data it removes from file it throws null pointer
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService es = Executors.newSingleThreadExecutor();
List<String> tasks = getUsersFromFile("new_users.txt");
DoctorDao dao = new DoctorDao();
for (String data : tasks) {
Future<Boolean> result = es.submit(new DoctorTask(data, dao));
while (result.get()) {
System.out.println("data stored!!!");
}
}
es.shutdown();
System.out.println("task done!!!");
}
public static List<String> getUsersFromFile(String fileName) {
List<String> users = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)))) {
String line = null;
while ((line = reader.readLine()) != null) {
users.add(line);
}
} catch (FileNotFoundException ex) {
// Logger.getLogger(TestExecutors.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
// Logger.getLogger(TestExecutors.class.getName()).log(Level.SEVERE, null, ex);
}
return users;
In Callable implemented class
public Boolean call() throws Exception {
Boolean status = false;
System.out.println(Thread.currentThread().getName() + " processing record for : " + doctorRecord);
StringTokenizer tokenizer = new StringTokenizer(this.doctorRecord, ",");
Doctor doc = null;
while (tokenizer.hasMoreTokens()) {
doc = new Doctor();
doc.setEmailAddress(tokenizer.nextToken());
doc.setName(tokenizer.nextToken());
doc.setId(Integer.valueOf(tokenizer.nextToken()));
status = dao.saveUser(doc);
}
return status;
}
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.executor.demo.readfile.TestDotorExecutor.main(TestDotorExecutor.java:23)
Caused by: java.lang.NullPointerException
at com.executor.demo.readfile.DoctorDao.saveUser(DoctorDao.java:5)
at com.executor.demo.readfile.DoctorTask.call(DoctorTask.java:28)
at com.executor.demo.readfile.DoctorTask.call(DoctorTask.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I made a mistake in the code I returned a null value from statiDB class, I didn't intialize List Object, so I modified the code as shown below
This complete code below was missing in above question
In dao class:
public class DoctorDao {
public boolean saveUser(Doctor doc) {
boolean storedStatus = StaticDB.getDoctorList().add(doc);
return storedStatus;
}
}
In DB class
class StaticDB {
static List<Doctor> docList=null;
public static List<Doctor> getDoctorList() {
Doctor doc1 = new Doctor(111,"Shalu","ss#gmail.com");
Doctor doc2 = new Doctor(112,"luke","luke#gmail.com");
docList = new ArrayList<Doctor>(); //This was missing
docList.add(doc1);
docList.add(doc2);
return docList;
}
}

spring batch job stuck in loop even when ItemReader returns null

I am converting xml to csv using spring batch and integration. I have a approach that job will start by reading files in from landing dir. while processing it will move files in inprocess dir. on error file will be moved to error dir. on successfully processing/writing file will be moved to output/completed.
After searching a while i got to know that there must be problem with itemreader but it is also returning null. I am not getting where is the problem.
Below is my batch configuration
#Bean
public Job commExportJob(Step parseStep) throws IOException {
return jobs.get("commExportJob")
.incrementer(new RunIdIncrementer())
.flow(parseStep)
.end()
.listener(listener())
.build();
}
#Bean
public Step streamStep() throws IOException {
CommReader itemReader = itemReader(null);
if (itemReader != null) {
return
steps.get("streamStep")
.<Object, Object>chunk(env.getProperty(Const.INPUT_READ_CHUNK_SIZE, Integer.class))
.reader(itemReader)
.processor(itemProcessor())
.writer(itemWriter(null))
.listener(getChunkListener())
.build();
}
return null;
}
#Bean
#StepScope
public ItemWriter<Object> itemWriter(#Value("#{jobParameters['outputFilePath']}") String outputFilePath) {
log.info("CommBatchConfiguration.itemWriter() : " + outputFilePath);
CommItemWriter writer = new CommItemWriter();
return writer;
}
#Bean
#StepScope
public CommReader itemReader(#Value("#{jobParameters['inputFilePath']}") String inputFilePath) {
log.info("CommBatchConfiguration.itemReader() : " + inputFilePath);
CommReader reader = new CommReader(inputFilePath);
// reader.setEncoding(env.getProperty("char.encoding","UTF-8"));
return reader;
}
#Bean
#StepScope
public CommItemProcessor itemProcessor() {
log.info("CommBatchConfiguration.itemProcessor() : Entry");
return new CommItemProcessor(ruleService);
}
CommReader.java
File inputFile = null;
private String jobName;
public CommReader(String inputFilePath) {
inputFile = new File(inputFilePath);
}
#Value("#{stepExecution}")
private StepExecution stepExecution;
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
#Override
public Object read() throws IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
if (inputFile.exists()) {
try {
builder = factory.newDocumentBuilder();
log.info("CommReader.read() :" + inputFile.getAbsolutePath());
Document document = builder.parse(inputFile);
return document;
} catch (ParserConfigurationException | SAXException | TransformerFactoryConfigurationError e) {
log.error("Exception while reading ", e);
}
}
return null;
}
#Override
public void close() throws ItemStreamException {
}
#Override
public void open(ExecutionContext arg0) throws ItemStreamException {
}
#Override
public void update(ExecutionContext arg0) throws ItemStreamException {
}
#Override
public void setResource(Resource arg0) {
}
CommItemProcessor.java
#Autowired
CommExportService ruleService;
public CommItemProcessor(CommExportService ruleService) {
this.ruleService = ruleService;
}
#Override
public Object process(Object bean) throws Exception {
log.info("CommItemProcessor.process() : Item Processor : " + bean);
return bean;
}
CommItemWriter.java
FlatFileItemWriter<byte[]> delegate;
ExecutionContext execContext;
FileOutputStream fileWrite;
File stylesheet;
StreamSource stylesource;
Transformer transformer;
List<List<?>> itemsTotal = null;
int recordCount = 0;
#Autowired
FileUtil fileUtil;
#Value("${input.completed.dir}")
String completedDir;
#Value("${input.inprocess.dir}")
String inprocessDir;
public void update(ExecutionContext arg0) throws ItemStreamException {
this.delegate.update(arg0);
}
public void open(ExecutionContext arg0) throws ItemStreamException {
this.execContext = arg0;
this.delegate.open(arg0);
}
public void close() throws ItemStreamException {
this.delegate.close();
}
#Override
public void write(List<? extends Object> items) throws Exception {
log.info("CommItemWriter.write() : items.size() : " + items.size());
stylesheet = new File("./config/style.xsl");
stylesource = new StreamSource(stylesheet);
String fileName = fileUtil.getFileName();
try {
transformer = TransformerFactory.newInstance().newTransformer(stylesource);
} catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
log.error("Exception while writing",e);
}
for (Object object : items) {
log.info("CommItemWriter.write() : Object : " + object.getClass().getName());
log.info("CommItemWriter.write() : FileName : " + fileName);
Source source = new DOMSource((Document) object);
Result outputTarget = new StreamResult(
new File(fileName));
transformer.transform(source, outputTarget);
}
}
In chunkListener there is nothing much i am doing.
Below is the job listener.
#Override
public void beforeJob(JobExecution jobExecution) {
log.info("JK: CommJobListener.beforeJob()");
}
#Override
public void afterJob(JobExecution jobExecution) {
log.info("JK: CommJobListener.afterJob()");
JobParameters jobParams = jobExecution.getJobParameters();
File inputFile = new File(jobParams.getString("inputFilePath"));
File outputFile = new File(jobParams.getString("outputFilePath"));
try {
if (jobExecution.getStatus().isUnsuccessful()) {
Files.move(inputFile.toPath(), Paths.get(inputErrorDir, inputFile.getName()),
StandardCopyOption.REPLACE_EXISTING);
Files.move(outputFile.toPath(), Paths.get(outputErrorDir, outputFile.getName()),
StandardCopyOption.REPLACE_EXISTING);
} else {
String inputFileName = inputFile.getName();
Files.move(inputFile.toPath(), Paths.get(inputCompletedDir, inputFileName),
StandardCopyOption.REPLACE_EXISTING);
Files.move(outputFile.toPath(), Paths.get(outputCompletedDir, outputFile.getName()),
StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException ioe) {
log.error("IOException occured ",ioe);
}
}
I am also using integration flow.
#Bean
public IntegrationFlow messagesFlow(JobLauncher jobLauncher) {
try {
Map<String, Object> headers = new HashMap<>();
headers.put("jobName", "commExportJob");
return IntegrationFlows
.from(Files.inboundAdapter(new File(env.getProperty(Const.INPUT_LANDING_DIR)))
,
e -> e.poller(Pollers
.fixedDelay(env.getProperty(Const.INPUT_POLLER_DELAY, Integer.class).intValue())
.maxMessagesPerPoll(
env.getProperty(Const.INPUT_MAX_MESSAGES_PER_POLL, Integer.class).intValue())
.taskExecutor(getFileProcessExecutor())))
.handle("moveFile","moveFile")
.enrichHeaders(headers)
.transform(jobTransformer)
.handle(jobLaunchingGw(jobLauncher))
.channel("nullChannel").get();
} catch (Exception e) {
log.error("Exception in Integration flow",e);
}
return null;
}
#Autowired
private Environment env;
#Bean
public MessageHandler jobLaunchingGw(JobLauncher jobLauncher) {
return new JobLaunchingGateway(jobLauncher);
}
#MessagingGateway
public interface IMoveFile {
#Gateway(requestChannel = "moveFileChannel")
Message<File> moveFile(Message<File> inputFileMessage);
}
#Bean(name = "fileProcessExecutor")
public Executor getFileProcessExecutor() {
ThreadPoolTaskExecutor fileProcessExecutor = new ThreadPoolTaskExecutor();
fileProcessExecutor.setCorePoolSize(env.getRequiredProperty(Const.INPUT_EXECUTOR_POOLSIZE, Integer.class));
fileProcessExecutor.setMaxPoolSize(env.getRequiredProperty(Const.INPUT_EXECUTOR_MAXPOOLSIZE, Integer.class));
fileProcessExecutor.setQueueCapacity(env.getRequiredProperty(Const.INPUT_EXECUTOR_QUEUECAPACITY, Integer.class));
fileProcessExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
fileProcessExecutor.initialize();
return fileProcessExecutor;
}
Try to return document itself instead of Object in read method of CommReader.java and then check whether its coming null or not in the writer to stop it.

Entity Framework The context cannot be used while the model is being created

My unit of work class is mentioned below and I am using Ninject and I have tried injecting IUnitOfWork per request per thread scope, transient etc. but I am still getting error which is:
"Message":"An error has occurred.","ExceptionMessage":"The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.","ExceptionType":"System.InvalidOperationException
I get this error when i make two web API (get) calls at the same time using angularJS and it shows error at the point _context.Set<TEntity>().FirstOrDefault(match);
public class UnitOfWork : IUnitOfWork, IDisposable
{
private My_PromotoolEntities _uowDbContext = new My_PromotoolEntities();
private Dictionary<string, object> _repositories;
// Do it like this if no specific class file
private GenericRepository<MysPerson> _personRepository;
//private GenericRepository<MysDataSource> dataSourcesRepository;
//private GenericRepository<MysCountry> countryMasterRepository;
// Or like this if with specific class file.
private DataSourceRepository _dataSourcesRepository;
private CustomerRepository _customerRepository;
private DeviceRepository _deviceRepository;
private DeviceRegistrationRepository _deviceRegistrationRepository;
private EmailQueueRepository _emailQueueRepository;
public void SetContext(My_PromotoolEntities context)
{
_uowDbContext = context;
}
public void CacheThis(object cacheThis, string keyName, TimeSpan howLong)
{
Cacheing.StaticData.CacheStaticData(cacheThis, keyName, howLong);
}
public object GetFromCache(string keyName)
{
return Cacheing.StaticData.GetFromCache(keyName);
}
public GenericRepository<T> GenericRepository<T>() where T : BaseEntity
{
if (_repositories == null)
{
_repositories = new Dictionary<string, object>();
}
var type = typeof(T).Name;
if (!_repositories.ContainsKey(type))
{
var repositoryType = typeof(GenericRepository<>);
var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof(T)), _uowDbContext);
_repositories.Add(type, repositoryInstance);
}
return (GenericRepository<T>)_repositories[type];
}
public GenericRepository<MysPerson> PersonRepository
{
get
{
if (this._personRepository == null)
{
this._personRepository = new GenericRepository<MysPerson>(_uowDbContext);
}
return _personRepository;
}
}
public DataSourceRepository DataSourcesRepository
{
get
{
if (this._dataSourcesRepository == null)
{
this._dataSourcesRepository = new DataSourceRepository(_uowDbContext);
}
return _dataSourcesRepository;
}
}
public CustomerRepository CustomerRepository
{
get
{
if (this._customerRepository == null)
{
this._customerRepository = new CustomerRepository(_uowDbContext);
}
return _customerRepository;
}
}
public DeviceRepository DeviceRepository
{
get
{
if (this._deviceRepository == null)
{
this._deviceRepository = new DeviceRepository(_uowDbContext);
}
return _deviceRepository;
}
}
public DeviceRegistrationRepository DeviceRegistrationRepository
{
get
{
if (this._deviceRegistrationRepository == null)
{
this._deviceRegistrationRepository = new DeviceRegistrationRepository(_uowDbContext);
}
return _deviceRegistrationRepository;
}
}
public EmailQueueRepository emailQueueRepository
{
get
{
if (this._emailQueueRepository == null)
{
this._emailQueueRepository = new EmailQueueRepository(_uowDbContext);
}
return _emailQueueRepository;
}
}
/// <summary>
/// Commits all changes to the db. Throws exception if fails. Call should be in a try..catch.
/// </summary>
public void Save()
{
try
{
_uowDbContext.SaveChanges();
}
catch (DbEntityValidationException dbevex)
{
// Entity Framework specific errors:
StringBuilder sb = new StringBuilder();
var eve = GetValidationErrors();
if (eve.Count() > 0)
{
eve.ForEach(error => sb.AppendLine(error));
}
ClearContext();
// Throw a new exception with original as inner.
var ex = new Exception(sb.ToString(), dbevex);
ex.Source = "DbEntityValidationException";
throw ex;
}
catch (Exception)
{
ClearContext();
throw;
}
}
private void ClearContext()
{
DetachAll();
}
private void DetachAll()
{
foreach (DbEntityEntry dbEntityEntry in _uowDbContext.ChangeTracker.Entries())
{
if (dbEntityEntry.Entity != null)
{
dbEntityEntry.State = EntityState.Detached;
}
}
}
/// <summary>
/// Checks for EF DbEntityValidationException(s).
/// </summary>
/// <returns>Returns a List of string containing the EF DbEntityValidationException(s).</returns>
public List<string> GetValidationErrors()
{
if (_uowDbContext.GetValidationErrors().Count() != 0)
{
return _uowDbContext.GetValidationErrors().Select(e => string.Join(Environment.NewLine, e.ValidationErrors.Select(v => string.Format("{0} - {1}", v.PropertyName, v.ErrorMessage)))).ToList();
}
return null;
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_uowDbContext.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
You should never use a context in 2 places at the same time, that's exactly why you are getting this error. From the MSDN documentation:
Thread Safety: Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
It is a little hard to make suggestions without a repro but there is a brute force approach that should resolve the issue. If you have an interception point before/during DI setup then you can cause all the context initialization etc to happen by creating an instance of your context and calling ctx.Database.Initialize(force: false); Passing 'force: false' will ensure that the initialization still only happens once per AppDomain

Custom enum marshaling with JAXB and moxy

I am having some trouble with custom enum marshaling with Moxy and JSON. My use case is that I have a large object model that includes enumerations that normally should provide a normal enumerated value, a "code", and a description. The source of this data has only the "code", so I need to be able to unmarshal instances of these enums using only the code (e.g.
{"companyCode":{"code":"PI"}}.
However, I should also be able to marshal and unmarshal all three fields:
{"companyCode":
{"value":"Private",
"code":"PI","description":
"Private Ins"
}
}
I am using an adapter that looks like this:
public class CodeEnumXmlAdapter<E extends Enum<E> & CodeEnum> extends XmlAdapter<CodeEnumImpl,E> {
public static <T extends Enum<T> & CodeEnum> T getFromName(Class<T> clazz, String name) {
if (name == null) return null;
T[] values = clazz.getEnumConstants();
for (T t : values) {
if (name.equals(t.name())) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & CodeEnum> T getFromCode(Class<T> clazz, String code) {
if (code == null) return null;
T[] values = clazz.getEnumConstants();
for (T t : values) {
if (code.equals(t.getCode())) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & CodeEnum> T getFromString(Class<T> clazz, String aString) {
if (aString == null) return null;
T[] values = clazz.getEnumConstants();
for (T t : values) {
if (aString.equals(t.getCode()) || aString.equals(t.name()) || aString.equals(t.getDescription())) {
return t;
}
}
return null;
}
#Override
public E unmarshal(CodeEnumImpl value) throws Exception {
if (value == null) return null;
String valueString = value.getValue();
if (valueString == null)
valueString = value.getCode();
if (valueString == null)
valueString = value.getDescription();
if (valueString == null)
return null;
Type generic = ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return getFromString((Class<E>)generic, valueString);
}
#Override
public CodeEnumImpl marshal(E value) throws Exception {
return value == null ? null : new CodeEnumImpl(value);
}
}
This converts from a an enum like this:
import org.apache.commons.lang3.StringUtils;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
#XmlJavaTypeAdapter(CompanyCode.Adapter.class)
public enum CompanyCode implements CodeEnum {
// Changed "Commmercial" to "Client" based on inputs from ...Greg, Tamil
Client("CM", "Client"), Medicare("MC", "Medicare"), Medicaid("MD",
"Medicaid"), Private("PI", "Private Ins"), Patient("PT", "Patient");
private String code;
private String description;
private CompanyCode(String code, String label) {
this.code = code;
this.description = label;
}
public String getDescription() {
return description;
}
public String getCode() {
return code;
}
public static CompanyCode fromCode(String code) {
if (StringUtils.isEmpty(code)) {
return null;
}
for (CompanyCode freq : values()) {
if (freq.getCode().equalsIgnoreCase(code)) {
return freq;
}
}
throw new IllegalArgumentException("Invalid CompanyCode code: " + code);
}
public String toString() {
return description;
}
public static class Adapter extends CodeEnumXmlAdapter<CompanyCode> {}
}
and uses and intermediate type like this:
import javax.xml.bind.annotation.XmlElement;
/**
* Created by Jeffrey Hoffman on 6/24/2015.
*/
public class CodeEnumImpl {
String value;
String description;
String code;
public CodeEnumImpl() {
}
public <E extends Enum<E> & CodeEnum> CodeEnumImpl(E value) {
if (value != null) {
this.value = value.name();
this.description = value.getDescription();
this.code = value.getCode();
}
}
#XmlElement
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#XmlElement
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#XmlElement
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Override
public String toString() {
return value == null ? null : value.toString();
}
}
This is working fine with straight XML and JAXB. However, when I try to use Moxy, I get an exception like this:
Exception Description: The object [Private Ins], of class [class
com.labcorp.phoenix.biz.enums.CompanyCode], could not be converted to
[class java.lang.Object]. Internal Exception: Exception
[EclipseLink-115] (Eclipse Persistence Services -
2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DescriptorException Exception
Description: No conversion value provided for the attribute [Private].
Mapping:
org.eclipse.persistence.oxm.mappings.XMLDirectMapping[companyCode-->companyCode/text()]
Descriptor: XMLDescriptor(com.labcorp.phoenix.eligibility.Root -->
[DatabaseTable(root)]) at
org.eclipse.persistence.exceptions.ConversionException.couldNotBeConverted(ConversionException.java:87)
at
org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter.convertObjectValueToDataValue(XMLJavaTypeConverter.java:178)
at
org.eclipse.persistence.oxm.mappings.XMLDirectMapping.convertObjectValueToDataValue(XMLDirectMapping.java:511)
at
org.eclipse.persistence.oxm.mappings.XMLDirectMapping.getFieldValue(XMLDirectMapping.java:330)
at
org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue.marshalSingleValue(XMLDirectMappingNodeValue.java:62)
at
org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue.marshal(XMLDirectMappingNodeValue.java:58)
at
org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102)
at
org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59)
at
org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:393)
at
org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:368)
at
org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:238)
at
org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118)
at
org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1)
at
org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:743)
at
org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:1124)
at
org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:869)
... 7 more Caused by: Exception [EclipseLink-115] (Eclipse
Persistence Services - 2.5.0.v20130507-3faac2b):
org.eclipse.persistence.exceptions.DescriptorException
It seems like a bug in moxy, because my adapter converts to a non-enum type, so there should not be a nestedConverter that deals with enums.
I managed to reproduce your issue with 2.5.0. It's most probably bug which has been fixed already. Unable to find the bug in Eclipse Bugzilla, but the same code works correctly with 2.6.0. Are you able to upgrade to latest MOXy?

MEF's GetExports<T, TMetadataView>() fails to find composed parts in the CompositionContainer

When attempting to load an instantiated export with GetExports() (using a LINQ query described below), the method returns null. I notice that when I call GetExports without the LINQ query, the return value is Count: 0. This would indicate to me that MEF is failing to find any exports that have been composed in the container. I can see the ExportDefinition, however, when looking at Container.Catalog.Parts.ExportDefinitions. Any ideas on where I am going wrong? Everything up until the query seems to be working fine.
I have the following contract and metadata view declared and implemented:
public interface IMap
{
void Init();
int ParseData();
}
public interface IMapMetadata
{
string MapName { get; }
string DocumentType { get; }
}
[Export(typeof(IMap))]
[ExportMetadata("MapName", "Map")]
public class Map
{
public Map()
{
}
}
I am using the following code to load a directory that contains DLLs that satisfy this contract with:
public void LoadByDirectory(string zPath)
{
try
{
_catalog.Catalogs.Add(new DirectoryCatalog(zPath));
}
catch (Exception e)
{
String zErrMess = e.Message;
}
}
Using a LINQ query to get an export:
public IMap GetMapInstance(string zMapName)
{
IMap ndeMap;
_container = new CompositionContainer(_catalog);
_container.ComposeParts(this);
try
{
ndeMap = _container.GetExports<IMap, IMapMetadata>()
.Where(p => p.Metadata.MapName.Equals(zMapName))
.Select(p => p.Value)
.FirstOrDefault();
}
catch (Exception ex)
{
throw new Exception("Failed to load map " + zMapName + ": " + ex.Message, ex);
}
return ndeMap;
}
Calling the above method like this:
IMap map = mapFactory.GetMapInstance("Map");
returns null.
UPDATED
In addition to the answer below, I was forgetting to declare the interface on the map class, this resolves the issue (note I removed the DocumentType property):
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MapExportAttribute : ExportAttribute, IMapMetadata
{
public MapExportAttribute()
: base(typeof(IMap))
{
}
public string MapName { get; set; }
}
[MapExport(MapName="Map")]
public class Map : IMap
{
public Map()
{
}
public void Init()
{
throw new NotImplementedException();
}
public int ParseData()
{
throw new NotImplementedException();
}
}
It looks like you're missing the DocumentType meta-data on your export:
[Export(typeof(IMap))]
[ExportMetadata("MapName", "Map")]
[ExportMetadata("DocumentType", "???")]
public class Map
{
}
The simplest way to ensure you specify the correct meta-data is a custom export attribute:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MapExportAttribute : ExportAttribute, IMapMetadata
{
public MapExportAttribute() : base(typeof(IMap))
{
}
public string MapName { get; set; }
public string DocumentType { get; set; }
}
[MapExport(MapName = "Map")]
public class Map
{
}

Resources