我正在使用Wildfly 9.0.0.CR2。如何启用JSP的动态编译?我在另一个线程中找到了这个配置
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
public sealed class MockDbSet<TEntity> : DbSet<TEntity>, IQueryable,
IEnumerable<TEntity>, IDbAsyncEnumerable<TEntity> where TEntity : class
{
public MockDbSet(MockDbContext context)
{
// Get entity set for entity
// Used when we figure out whether to generate
// IDENTITY values
EntitySet = ((IObjectContextAdapter) context).ObjectContext
.MetadataWorkspace
.GetItems<EntityContainer>(DataSpace.SSpace).First()
.BaseEntitySets
.FirstOrDefault(item => item.Name == typeof(TEntity).Name);
Data = new ObservableCollection<TEntity>();
Query = Data.AsQueryable();
}
private ObservableCollection<TEntity> Data { get; set; }
Type IQueryable.ElementType
{
get { return Query.ElementType; }
}
private EntitySetBase EntitySet { get; set; }
Expression IQueryable.Expression
{
get { return Query.Expression; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return Data.GetEnumerator();
}
public override ObservableCollection<TEntity> Local
{
get { return Data; }
}
IQueryProvider IQueryable.Provider
{
get { return new MockDbAsyncQueryProvider<TEntity>(Query.Provider); }
}
private IQueryable Query { get; set; }
public override TEntity Add(TEntity entity)
{
GenerateIdentityColumnValues(entity);
Data.Add(entity);
return entity;
}
public override IEnumerable<TEntity> AddRange(IEnumerable<TEntity> entities)
{
foreach (var entity in entities)
Add(entity);
return entities;
}
public override TEntity Attach(TEntity entity)
{
return Add(entity);
}
public override TEntity Create()
{
return Activator.CreateInstance<TEntity>();
}
public override TDerivedEntity Create<TDerivedEntity>()
{
return Activator.CreateInstance<TDerivedEntity>();
}
public override TEntity Find(params object[] keyValues)
{
throw new NotSupportedException();
}
public override Task<TEntity> FindAsync(params object[] keyValues)
{
return FindAsync(CancellationToken.None, keyValues);
}
public override Task<TEntity> FindAsync(CancellationToken cancellationToken, params object[] keyValues)
{
throw new NotSupportedException();
}
private void GenerateIdentityColumnValues(TEntity entity)
{
// The purpose of this method, which is called when adding a row,
// is to ensure that Identity column values are properly initialized
// before performing the add. If we were making a "real" Entity Framework
// Add() call, this task would be handled by the data provider and the
// value(s) would then be propagated back into the entity. In the case
// of this mock, there is nothing that will do that, so we have to make
// this at-least token effort to ensure the columns are properly initialized.
// In SQL Server, an Identity column can be of one of the following
// data types: tinyint, smallint, int, bigint, decimal (with a scale of 0),
// or numeric (with a scale of 0); This method handles the integer types
// (the others are typically not used).
foreach (var member in EntitySet.ElementType.Members.ToList())
{
if (member.IsStoreGeneratedIdentity)
{
// OK, we've got a live one; do our thing.
//
// Note that we'll get the current value of the column and,
// if it is nonzero, we'll leave it alone. We do this because
// the test data in our mock DbContext provides values for the
// Identity columns and many of those values are foreign keys
// in other entities (where we also provide test data). We don't
// want to disturb any existing relationships defined in the test data.
Type columnDataType = null;
foreach (var metadataProperty in member.TypeUsage.EdmType.MetadataProperties.ToList())
{
if (metadataProperty.Name != "PrimitiveTypeKind")
continue;
switch ((PrimitiveTypeKind)metadataProperty.Value)
{
case PrimitiveTypeKind.SByte:
columnDataType = typeof(SByte);
break;
case PrimitiveTypeKind.Int16:
columnDataType = typeof(Int16);
break;
case PrimitiveTypeKind.Int32:
columnDataType = typeof(Int32);
break;
case PrimitiveTypeKind.Int64:
columnDataType = typeof(Int64);
break;
default:
throw new InvalidOperationException();
}
var identityColumnGetter = entity.GetType().GetProperty(member.Name).GetGetMethod();
var identityColumnSetter = entity.GetType().GetProperty(member.Name).GetSetMethod();
Int64 specifiedColumnValue = 0;
switch (columnDataType.Name)
{
case "SByte":
specifiedColumnValue = (SByte)identityColumnGetter.Invoke(entity, null);
break;
case "Int16":
specifiedColumnValue = (Int16)identityColumnGetter.Invoke(entity, null);
break;
case "Int32":
specifiedColumnValue = (Int32)identityColumnGetter.Invoke(entity, null);
break;
case "Int64":
specifiedColumnValue = (Int64)identityColumnGetter.Invoke(entity, null);
break;
}
if (specifiedColumnValue != 0)
break;
Int64 maxExistingColumnValue = 0;
switch (columnDataType.Name)
{
case "SByte":
foreach (var item in Local.ToList())
maxExistingColumnValue = Math.Max(maxExistingColumnValue, (SByte)identityColumnGetter.Invoke(item, null));
identityColumnSetter.Invoke(entity, new object[] { (SByte)(++maxExistingColumnValue) });
break;
case "Int16":
foreach (var item in Local.ToList())
maxExistingColumnValue = Math.Max(maxExistingColumnValue, (Int16)identityColumnGetter.Invoke(item, null));
identityColumnSetter.Invoke(entity, new object[] { (Int16)(++maxExistingColumnValue) });
break;
case "Int32":
foreach (var item in Local.ToList())
maxExistingColumnValue = Math.Max(maxExistingColumnValue, (Int32)identityColumnGetter.Invoke(item, null));
identityColumnSetter.Invoke(entity, new object[] { (Int32)(++maxExistingColumnValue) });
break;
case "Int64":
foreach (var item in Local.ToList())
maxExistingColumnValue = Math.Max(maxExistingColumnValue, (Int64)identityColumnGetter.Invoke(item, null));
identityColumnSetter.Invoke(entity, new object[] { (Int64)(++maxExistingColumnValue) });
break;
}
}
}
}
}
IDbAsyncEnumerator<TEntity> IDbAsyncEnumerable<TEntity>.GetAsyncEnumerator()
{
return new MockDbAsyncEnumerator<TEntity>(Data.GetEnumerator());
}
IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
{
return Data.GetEnumerator();
}
public override TEntity Remove(TEntity entity)
{
Data.Remove(entity);
return entity;
}
public override IEnumerable<TEntity> RemoveRange(IEnumerable<TEntity> entities)
{
foreach (var entity in entities)
Remove(entity);
return entities;
}
public override DbSqlQuery<TEntity> SqlQuery(string sql, params object[] parameters)
{
throw new NotSupportedException();
}
}
internal class MockDbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider
{
internal MockDbAsyncQueryProvider(IQueryProvider queryProvider)
{
QueryProvider = queryProvider;
}
private IQueryProvider QueryProvider { get; set; }
public IQueryable CreateQuery(Expression expression)
{
return new MockDbAsyncEnumerable<TEntity>(expression);
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new MockDbAsyncEnumerable<TElement>(expression);
}
public object Execute(Expression expression)
{
return QueryProvider.Execute(expression);
}
public TResult Execute<TResult>(Expression expression)
{
return QueryProvider.Execute<TResult>(expression);
}
public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute(expression));
}
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute<TResult>(expression));
}
}
internal class MockDbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T>
{
public MockDbAsyncEnumerable(IEnumerable<T> enumerable)
: base(enumerable)
{
}
public MockDbAsyncEnumerable(Expression expression)
: base(expression)
{
}
IQueryProvider IQueryable.Provider
{
get { return new MockDbAsyncQueryProvider<T>(this); }
}
public IDbAsyncEnumerator<T> GetAsyncEnumerator()
{
return new MockDbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
}
IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
{
return GetAsyncEnumerator();
}
}
internal class MockDbAsyncEnumerator<T> : IDbAsyncEnumerator<T>
{
public MockDbAsyncEnumerator(IEnumerator<T> enumerator)
{
Enumerator = enumerator;
}
public void Dispose()
{
Enumerator.Dispose();
}
public T Current
{
get { return Enumerator.Current; }
}
object IDbAsyncEnumerator.Current
{
get { return Current; }
}
private IEnumerator<T> Enumerator { get; set; }
public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Enumerator.MoveNext());
}
}
}
但是,它不起作用,当我重新启动JBoss服务器时会导致以下异常...
<subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false">
<configuration>
<jsp-configuration development="true" check-interval="1" modification-test-interval="1" recompile-on-fail="true"/>
</configuration>
</subsystem>
答案 0 :(得分:4)
这是一个XML解析问题,此错误消息javax.xml.stream.XMLStreamException: ParseError
就是明证。此特定行Unexpected element{urn:jboss:domain:web:1.4}subsystem
的解析失败。
您可以查看XML模式文档以找出这些类型的XML解析问题。模式位于WildFly的docs文件夹下。
顺便说一句,您应该使用WildFly-9.0.1.Final
构建版本,因为这是最新的候选版本。
您很可能需要对underow子系统进行更改。我已经更新了以下示例:
<subsystem xmlns="urn:jboss:domain:undertow:2.0">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
<servlet-container name="default">
<jsp-config development="true" check-interval="1" modification-test-interval="1" recompile-on-fail="true"/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<response-header name="server-header" header-name="Server" header-value="WildFly/9"/>
<response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
</filters>
</subsystem>
我强烈建议您使用CLI进行此类更改:
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=development,value=true)
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=recompile-on-fail,value=true)
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=check-interval,value=1)
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=modification-test-interval,value=1)
通过这种方式,您可以避免这些XML解析错误,而无需查找确切的XML模式。
答案 1 :(得分:3)
搜索子系统并在jsp config上添加它
<subsystem xmlns="urn:jboss:domain:undertow:1.1"><br>. . . .<br> <servlet-container name="default" default-buffer-cache="default" stack-trace-on-error="local-only">
<jsp-config development="true" check-interval="1" modification-test-interval="1" recompile-on-fail="true"/>
答案 2 :(得分:1)
确保您正在加载底部延伸。否则,子系统配置无法加载。除此之外,你的语法是正确的。
<extensions>
<!-- other extensions here -->
<extension module="org.wildfly.extension.undertow"/>
</extensions>